Skip to content

Instantly share code, notes, and snippets.

@ormaaj
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ormaaj/0c7f092ef27908ed610a to your computer and use it in GitHub Desktop.
Save ormaaj/0c7f092ef27908ed610a to your computer and use it in GitHub Desktop.
How not to read lines.
#!/usr/bin/env bash
# bash / ksh93 / mksh / zsh
# Don't do this!
${ZSH_VERSION+false} || emulate ksh
unset -v isKsh93
[[ ${!KSH_VERSION} == .sh.version ]] && isKsh93=
# Reads lines from file or stdin into arrayName, stupidly.
# evilReadLines arrayName [ file ]
function evilReadLines {
# Ensure $1 is nonempty, and $2 is either a readable file, or if $2 is
# unset, stdin isn't a terminal.
[[ -n $1 && ( -r $2 || ( -z ${2+_} && ! -t 0 ) ) ]] || return
# Make $1 a reference parameter, and the a local var of the same name a
# reference to $1, in ksh93 only.
${isKsh93+eval typeset -n "${1}=\$1"}
# Preserve the previous glob and brace expansion states.
# set options are only local in ksh93.
typeset -a onReturn
if [[ ! -o noglob ]]; then
set -f
onReturn+=('set +f')
fi
if [[ -o braceexpand ]]; then
set +o braceexpand
onReturn+=('set -o braceexpand')
fi
# Do the stupid word split.
IFS=$'\n' command eval "$1"'=($(<"${2:-/dev/fd/0}"))'
# Reset previous option states.
typeset cmd
for cmd in "${onReturn[@]}"; do
eval "$cmd"
done
}
function main {
# set -x; ${isKsh93+typeset -ft evilReadLines}
typeset -a myArray
# Pass in an array name and file name
evilReadLines myArray
typeset -p myArray
}
main <<\EOF
foo
bar
baz
EOF
# vim: set fenc=utf-8 ff=unix ft=sh :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment