build argument lists containing whitespace
In bash one can escape arguments that contain whitespace.
foo "a string"
This also works for arguments to a command or function:
bar() {
foo "$@"
}
bar "a string"
So far so good, but what if I want to manipulate the arguments before calling foo
?
This does not work:
bar() {
for arg in "$@"
do
args="$args \"prefix $arg\""
done
# Everything looks good ...
echo $args
# ... but it isn't.
foo $args
# foo "$args" would just be silly
}
bar a b c
So how do you build argument lists when the arguments contain whitespace?
There are (at least) two ways to do this:
-
Use an array and expand it using
"${array[@]}"
:bar() { local i=0 args=() for arg in "$@" do args[$i]="prefix $arg" ((++i)) done foo "${args[@]}" }
So, what have we learned?
"${array[@]}"
is to${array[*]}
what"$@"
is to$*
. -
Or if you do not want to use arrays you need to use
eval
:bar() { local args=() for arg in "$@" do args="$args \"prefix $arg\"" done eval foo $args }
Here is a shorter version which does not require the use of a numeric index:
(example: building arguments to a find
command)
dir=$1
shift
for f in "$@" ; do
args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
Use arrays (one of the hidden features in Bash).