Passing arrays as arguments in bash
I tend to avoid bash wherever possible for scripting, because it has dangerously bad defaults and will happily munge your data unless you take great care to wrap it up properly (particularly whitespace). But sometimes you have no choice, so you might as well know how to do it safely.
Here’s how to capture argv
as a bash array, and pass it on to another command without breaking if some argument contains a space:
args=("$@")
echo "${args[@]}"
You can also just pass “$@” directly, but the above syntax works for any array.
Don’t forget any of those quotes, or bash will silently ruin everything (until you have data with spaces, at which point it might loudy ruin everything).
Here’s how to convert a line-delimited string (e.g a list of files in the current directory) into an array and pass that on:
mapfile -t arr <<<"$(ls -1)"
echo "${arr[@]}"
Note that a sensible-looking:
ls -1 | mapfile -t args
will not work, as a builtin on the receiving end of a pipe gets run in a subshell.
If you don’t have mapfile
(added in bash v4), you’ll have to resort to:
oldIFS="$IFS"; IFS=$'\n' read -d '' -r -a arr <<< "$(ls -1)"; IFS="$oldIFS"; unset oldIFS
echo "${arr[@]}";
I look forward to the day when I don’t have to know that.