Bash的手册页说,关于-c
选项:
-c string
如果存在-c
选项,则从中读取命令string
的。如果之后有争论 字符串,它们被分配给 位置参数,从$0
。
所以鉴于这个描述,我认为这样的事情应该有效:
bash -c "echo arg 0: $0, arg 1: $1" arg1
但输出只显示以下内容,因此看起来-c
字符串后面的参数没有分配给位置参数。
arg 0: -bash, arg 1:
我正在运行一个相当古老的Bash(在Fedora 4上):
[root @dd42 trunk] #bash --version GNU bash,版本3.00.16(1)-release(i386-redhat-linux-gnu) 版权所有(C)2004 Free Software Foundation,Inc。
我真的想用参数执行一些shell脚本。我认为-c
看起来很有希望,因此上面的问题。我想知道使用eval,但我认为我不能将参数传递给eval之后的东西。我也对其他建议持开放态度。
答案 0 :(得分:34)
您需要使用单引号来防止在调用shell中发生插值。
$ bash -c 'echo arg 0: $0, arg 1: $1' arg1 arg2
arg 0: arg1, arg 1: arg2
或者在双引号字符串中转义变量。使用哪个可能取决于您想要在代码片段中添加的内容。
答案 1 :(得分:4)
因为字符串中的“$0
”和“$1
”分别被变量#0和#1替换。
尝试:
bash -c "echo arg 0: \$0, arg 1: \$1" arg0 arg1
在此代码$
中,两者都是escape,因此base将其视为字符串$
而不会被替换。
此命令的结果是:
arg 0: arg0, arg 1: arg1
希望这有帮助。
答案 2 :(得分:2)
向$0
添加一个反斜杠(即\$0
),否则你的当前shell会在它到达子shell之前将$0
转义为shell的名称。
答案 3 :(得分:2)
#!/bin/bash
echo 0:$0
echo 1:$1
echo 2:$2
然后你应该这样称呼:
$ bash -c './foo.sh ${1+"$@"}' foo "bar baz"
0:./foo.sh
1:bar baz
2:
或更一般地bash -c '${0} ${1+"$@"}' <command> [argument]...
$ bash -c ./foo.sh foo "bar baz"
0:./foo.sh
1:
2:
$ bash -c './foo.sh $@' foo "bar baz"
0:./foo.sh
1:bar
2:baz
这意味着您可以将参数传递给子进程,而无需将它们嵌入到命令字符串中,而无需担心转义它们。