$ @变得搞砸了

时间:2011-06-17 07:52:25

标签: bash shell

我正在尝试编写一个bash脚本来检查第一个参数,如果它是一个特定的值,那么它将从参数中删除该参数并设置一些内容:

#!/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=$@

但是,当我运行它时,它会消耗所有参数! 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=

如果没有遵循if语句:

./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==

发生了什么,以及如何解决?

4 个答案:

答案 0 :(得分:4)

这是因为set blah blah blah实际上将$1 ... $N参数设置为参数评估的参数,如下面的记录所示:

pax$ echo $1

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

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

(在第二个命令中,$tool未设置,这就是它为空白的原因。)

在您的情况下,set $tool=valgrind$1设置为字符串$tool=valgrind评估的内容,这就是$@正在发生变化的原因。 将环境变量tool设置为valgrind

如果要设置变量,只需使用:

tool=valgrind

或者,使它可用于子壳:

export tool=valgrind

set命令用于显示环境内容或设置shell属性和参数,而不是命名变量。如果您查看man bash_builtins联机帮助页,您会看到解释此行为的位(搜索set的说明):

  

处理选项后剩余的任何参数都被视为位置参数的值,并按顺序分配给$1, $2, ... $n

答案 1 :(得分:2)

set $tool=valgrind

应该是

tool=valgrind

set命令用于bash中的其他内容,请尝试'help set'。

答案 2 :(得分:0)

set $tool=valgrind应该只是tool=valgrind。与{B} / Bourne兼容的shell中的set与C shell中的不同。

答案 3 :(得分:0)

对于getopts处理,您也应该检查-x argumentSee here