I have a problem passing parameters if the parameters may contain wildcards and/or spaces, if those parameters are optional. Since this sounds pretty abstract, let's have a small example: The following shell script some_command.sh
expects 2 or 3 arguments. The first argument is supposed to be a command line switch, the second argument is optional and, if present, must be a command line switch of the form --NAME=VALUE
, and the final argument is required and can be anything:
#!/bin/bash
# This is file some_command.sh
# Synopsis:
# some_command.sh --switch1=val1 [--switch2=val2] arg
echo "switch1: $1"
shift
if [[ "$1" == --*=* ]]
then
echo "switch2 ($1) detected"
shift
fi
echo argument is ${1:?argument missing}
Let's assume that I am calling some_command.sh
from some other script, caller.sh
, in the following way:
#!/bin/bash
# This is file caller.sh
if [[ ${1:-x} == x ]]
then
switch="--abc=long argument"
else
switch=""
fi
some_command.sh "--exclude=*~" "$switch" arg
Note the quoting. The quotes around --exclude
are necessary, because the wildcard expression must not be expanded by the shell, and the quotes around "$switch"
are necessary, because $switch
may contain text having spaces, and the argument must not be broken up on the spaces.
The intention is that if we execute caller.sh x
, this should result into
some_command.sh "--exclude=*~" "--abc=long argument" arg
and if we execute, say, caller.sh y
, this should turn into
some_command.sh "--exclude=*~" arg
The caller.sh
which I have provided here, does not work correctly, because in the latter case, it would execute
some_command.sh "--exclude*~" "" arg
which is incorrect.
I tried to prefix the command with eval
. While this would solve the problem with $switch
, it would also remove the quotes around "--exclude"
, and the wildcards would be evaluated by the shell.
I guess I could go on with the eval
, and just use an extra level of quoting, i.e. "\"--exclude*~\""
, but this is an awful solution. I wonder if somebody has a cleaner way to do it.
In case you wonder why I came to this question: I stumbled over the problem when writing scripts invoking zip
, and since these scripts should be able to cope with spaces in file names.
BTW, the problem, as stated, occurs with bash
and zsh
. I am also interested in clever solutions, which work only with one of those shells.