Say I have a command I want to run (cmd
) and a variable containing the arguments I want to pass to the function (something like --foo 'bar baz' qux
). Like so:
#!/bin/sh
command=cmd
args="--foo 'bar baz' qux"
The arguments contain quotes, like the ones shown above, that group together an argument containing a space. I'd then like to run the command:
$command $args
This, of course, results in running the command with four arguments: --foo
, 'bar
, baz'
, and qux
. The alternative I'm used to (i.e., when using "$@"
) presents a different problem:
$command "$args"
This executes the command with one argument: --foo 'bar baz' qux
.
How can I run the command with three arguments (--foo
, bar baz
, and qux
) as intended?
Use an array to specify your argument list exactly, without string-splitting (which is what's doing the wrong thing here) getting in your way:
args=( --foo "bar baz" qux )
command "${args[@]}"
If you need to build your argument list dynamically, you can append to arrays with +=
:
args=( )
while ...; do
args+=( "$another_argument" )
done
call_your_subprocess "${args[@]}"
Note that the use of quotation marks, and [@]
instead of [*]
, is essential.
If you can throw away the current positional variables ($1
...) you can use the following:
set -- '--foo' 'bar baz' 'qux'
echo "$#" # Prints "3" (without quotes)
echo "$2" # Prints "bar baz" (without quotes)
command "$@"
Just tested it in a #!/usr/bin/env sh
script, so it works at least in Dash, and should work in any Bourne Shell variant. No eval
, Python or Bash necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With