2

I have a shell script that runs exec to replace itself with another command. The other command takes some optional arguments.

exec mycommand $ARG1 $ARG2 $ARG3

Any of these arguments could be populated or not populated. If they aren't populated, they don't render as an argument to the function. For example:

# if you have:
ARG1=foo
ARG3=bar
exec mycommand $ARG1 $ARG2 $ARG3
# then you get:
exec mycommand foo bar

However, I want spaces to be legal in the values for these arguments, and for this not to cause them to produce additional arguments. That is,

# if you have
ARG1="foo bar baz"
ARG2="qux"
exec mycommand $ARG1 $ARG2 $ARG3
# then I want:
exec mycommand "foo bar baz" qux
# not:
exec mycommand foo bar baz qux

I tried putting escaped quotes into the arguments, but exec expected them to literally be part of the value.

ARG1="\"foo bar baz\""
exec mycommand $ARG1 $ARG2 $ARG3
# gives you:
exec mycommand \"foo bar baz\"

I also tried quoting the variables in exec, but then it started passing empty strings when arguments weren't present:

ARG2="foo bar"
exec mycommand "$ARG1" "$ARG2" "$ARG3"
# gives you:
exec mycommand "" "foo bar" ""

Is there a better way to construct a command and pass it to exec? Is there another way to replace the current process with another one?

1

1 Answer 1

1

With bash, you use an array, and all variables must be properly quoted:

ARG1="foo bar baz"
ARG3="qux"

cmd=( mycmd )

[[ -n "$ARG1" ]] && cmd+=( "$ARG1" )
[[ -n "$ARG2" ]] && cmd+=( "$ARG2" )
[[ -n "$ARG3" ]] && cmd+=( "$ARG3" )

printf "%s\n" "${cmd[@]}"
#exec "${cmd[@]}"

This will give you the invocation you want: exec mycommand "foo bar baz" qux with no "empty string" arguments. Remove the printf line and uncomment the exec line if you're happy with how it's working.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .