I have a shell function called "run", that normally just treats its parameters as a command line (i.e., as though 'run()' had not been used.) However, if the script is run in a $TESTMODE
, 'run()' will echo its parameters, instead:
run ()
{
cmd="$@"
if [ -z "$TESTMODE" ]; then
$cmd
else
echo "### RUN: '$cmd'"
fi
}
The idea is, the command run rm -Rf /
would normally attempt to delete your entire root filesystem. But, if $TESTMODE is defined, then it instead echos
### RUN: rm -Rf /
It works pretty well, until you attempt to use run() on a command-line that includes redirection:
run which which
run which bash >quiet
In which case, when $TESTMODE
is defined, the desired echo
will never be seen by human eyes:
$ rm quiet
$ TESTMODE=yes ./runtest.sh
### RUN: 'which which'
$ cat quiet
### RUN: 'which bash'
I attempted to correct for this with string replacement:
run ()
{
cmd="$@"
if [ -z "$TESTMODE" ]; then
$cmd
else
cmd=${cmd//\>/\\>}
cmd=${cmd//\</\\<}
echo "### RUN: '$cmd'"
fi
}
... which seemed promising in a command-line test:
$ test1="foo >bar"
$ echo $test1
foo >bar
$ test2=${test1//\>/\\>}
$ echo $test2
foo \>bar
... but failed miserably (no apparent change in behavior) from within my bash script.
Help? I'm sure this has something to do with quoting, but I'm not sure exactly how to address it.