我正在尝试编写一个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==
发生了什么,以及如何解决?
答案 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 argument
。 See here