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

Chr*_*kle 29 bash eval

关于-c选项,Bash的手册页说:

-c string 如果-c存在该选项,则从中读取命令 string.如果字符串后面有参数,则将它们分配给位置参数,从 $0.

所以鉴于这个描述,我认为这样的事情应该有效:

bash -c "echo arg 0: $0, arg 1: $1" arg1
Run Code Online (Sandbox Code Playgroud)

但输出只显示以下内容,因此看起来-c字符串后的参数没有分配给位置参数.

arg 0: -bash, arg 1:
Run Code Online (Sandbox Code Playgroud)

我正在运行一个相当古老的Bash(在Fedora 4上):

[root @dd42 trunk] #bash --version GNU bash,version 3.00.16(1)-release(i386-redhat-linux-gnu)Copyright(C)2004 Free Software Foundation,Inc.

我真的想用参数执行一些shell脚本.我认为-c看起来非常有希望,因此上面的问题.我想知道使用eval,但我认为我不能将参数传递给eval之后的东西.我也对其他建议持开放态度.

mar*_*ton 37

您需要使用单引号来防止在调用shell中发生插值.

$ bash -c 'echo arg 0: $0, arg 1: $1' arg1 arg2
arg 0: arg1, arg 1: arg2
Run Code Online (Sandbox Code Playgroud)

或者转义双引号字符串中的变量.使用哪种方法可能取决于您要在代码片段中准确添加的内容.


Naw*_*Man 6

因为字符串中的' $0' 和 ' $1' 分别替换为变量 #0 和 #1。

尝试 :

bash -c "echo arg 0: \$0, arg 1: \$1" arg0 arg1
Run Code Online (Sandbox Code Playgroud)

在这段代码中$,两者都是转义的,因此基本将其视为字符串$而不是被替换。

这个命令的结果是:

arg 0: arg0, arg 1: arg1
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。


z0r*_*z0r 5

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

#!/bin/bash
echo 0:$0
echo 1:$1
echo 2:$2
Run Code Online (Sandbox Code Playgroud)

那么你应该这样称呼它

$ bash -c './foo.sh ${1+"$@"}' foo "bar baz"
0:./foo.sh
1:bar baz
2:
Run Code Online (Sandbox Code Playgroud)

或更一般地 bash -c '${0} ${1+"$@"}' <command> [argument]...

不是这样的

$ bash -c ./foo.sh foo "bar baz"
0:./foo.sh
1:
2:
Run Code Online (Sandbox Code Playgroud)

也不像这样

$ bash -c './foo.sh $@' foo "bar baz"
0:./foo.sh
1:bar
2:baz
Run Code Online (Sandbox Code Playgroud)

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