开发者

$@ becoming messed up

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 -开发者_JAVA技巧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 blah actually sets the $1 ... $N parameters to whatever the arguments evaluate to, as shown in the following transcript:

pax$ echo $1

pax$ set $tool=hello ; echo $1
=hello

pax$ tool=xyzzy ; set $tool=hello ; echo $1
xyzzy=hello

(in that second command, $tool is not set which is why it comes out as blank).

In your case, set $tool=valgrind is setting $1 to whatever the string $tool=valgrind evaluates to, which is why $@ is changing. It is not setting the environment variable tool to valgrind.

If you want to set the variable, just use:

tool=valgrind

or, to make it available to subshells:

export tool=valgrind

The set command is used to either display environment stuff or set shell attributes and arguments, not named variables. If you have a look at the man bash_builtins manpage, you'll see the bit that explains this behaviour (search for the description of set):

Any arguments remaining after the options are processed are treated as values for the positional parameters and are assigned, in order, to $1, $2, ... $n.


set $tool=valgrind

should be

tool=valgrind

The set command is for something else in bash, try 'help set'.


set $tool=valgrind should be just tool=valgrind. set has a different in Bash/Bourne-compatible shells than it has in the C shell.


You should check the getopts too, for the -x argument handling. See here

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜