set -- cat "a b"
"$@"
This would run cat
with the single argument a b
. The expansion of "$@"
(including the double quotes!) would be a list of individually quoted positional parameters. The positional parameters are set with set
.
It's uncommon to include the command name in the list itself though. It would be more common to see
set -- "a b"
cat "$@"
or, if you want to keep the actual command name variable,
cmd=cat
set -- "a b"
"$cmd" "$@"
If you, in-between setting the filename operands and running the command, want to add more filenames or options to the command, simply modify $@
:
cmd=cat
set -- "a b"
# later (adding more files to the end):
set -- "$@" "more files" "some glob here-"[0-9]
# later (adding an option at the front):
set -- -v "$@"
"$cmd" "$@"
Note that it becomes difficult to add to the front of $@
if the command name is already there. In that case you would have to temporary shift
the command name off of $@
into a separate variable, add the thing you want to add, and then add the command name again:
cmd=$1
shift
set -- "$cmd" -v "$@"
We usually want to use set --
rather than just set
to set the positional parameters. The --
stops the parser of command line options from detecting command line options past that point in the command line argument list. Note that without --
, it would be impossible to add the string -v
at the front of $@
with set
as set -v
does something quite different.
Related:
dash
(which doesn't provide theksh
/bash
array syntax) you should still be able to use the$@
array as described here Arrays in Unix Bourne Shell