I am trying to write a bash script that will examine the first argument, and if its one of particular values then it will remove that argument from the arguments and set some stuff up:
#!/bin/bash -x
echo args=$@
if [ "$1" == "valgrind" ]; then
echo running under valgrind
set $tool=valgrind
shift 1
elif [ "$1" == "debug" ]; then
echo running under gdb
set $tool=gdb --args
shift 1
else
echo running normally
set $tool=""
fi
echo tool=$tool
echo args=$@
However, When I run this it consumes all the arguments! E.g.:
./my_script valgrind --something=y -r
+ echo args=valgrind --something=y -r
args=valgrind --something=y -r
+ '[' valgrind == valgrind ']'
+ echo running under valgrind
running under valgrind
+ set =valgrind
+ shift 1
+ echo tool=
tool=
+ echo args=
args=
and if the if-statements aren’t followed:
./my_script valgrindx --something=y -r
+ echo args=valgrindx --something=y -r
args=valgrindx --something=y -r
+ '[' valgrindx == valgrind ']'
+ '[' valgrindx == debug ']'
+ echo running normally
running normally
+ set =
+ echo tool=
tool=
+ echo args==
args==
What is happening, and how to fix it?
It’s because
set blah blah blahactually sets the$1 ... $Nparameters to whatever the arguments evaluate to, as shown in the following transcript:(in that second command,
$toolis not set which is why it comes out as blank).In your case,
set $tool=valgrindis setting$1to whatever the string$tool=valgrindevaluates to, which is why$@is changing. It is not setting the environment variabletooltovalgrind.If you want to set the variable, just use:
or, to make it available to subshells:
The
setcommand is used to either display environment stuff or set shell attributes and arguments, not named variables. If you have a look at theman bash_builtinsmanpage, you’ll see the bit that explains this behaviour (search for the description ofset):