我似乎无法在“-c”选项字符串后面使用带有参数的Bash“-c”选项

时间:2009-11-10 23:25:29

标签: bash eval

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之后的东西。我也对其他建议持开放态度。

4 个答案:

答案 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)

马丁对插值是正确的:你需要使用单引号。但请注意,如果您尝试将参数传递给字符串中执行的命令,则需要明确转发它们。例如,如果您有一个脚本 foo.sh ,如:

#!/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]...

Not like this

$ bash -c ./foo.sh foo "bar baz"
0:./foo.sh
1:
2:

Nor like this

$ bash -c './foo.sh $@' foo "bar baz"
0:./foo.sh
1:bar
2:baz

这意味着您可以将参数传递给子进程,而无需将它们嵌入到命令字符串中,而无需担心转义它们。