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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1711970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:40:40  来源:igfitidea点击:

I can't seem to use the Bash "-c" option with arguments after the "-c" option string

basheval

提问by Chris Markle

The man page for Bash says, regarding the -coption:

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

-c stringIf the -coption is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

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

So given that description, I would think something like this ought to work:

因此,鉴于该描述,我认为这样的事情应该可行:

bash -c "echo arg 0: 
arg 0: -bash, arg 1:
, arg 1: " arg1

but the output just shows the following, so it looks like the arguments after the -cstring are not being assigned to the positional parameters.

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

$ bash -c 'echo arg 0: 
bash -c "echo arg 0: $0, arg 1: $1" arg0 arg1
, arg 1: ' arg1 arg2 arg 0: arg1, arg 1: arg2

I am running a fairly ancient Bash (on Fedora 4):

我正在运行一个相当古老的 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.

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

I am really trying to execute a bit of a shell script with arguments. I thought -clooked very promising, hence the issue above. I wondered about using eval, but I don't think I can pass arguments to the stuff that follows eval. I'm open to other suggestions as well.

我真的想用参数执行一些shell脚本。我认为-c看起来很有希望,因此出现了上述问题。我想知道如何使用 eval,但我不认为我可以将参数传递给 eval 之后的内容。我也愿意接受其他建议。

回答by martin clayton

You need to use single quotes to prevent interpolation happening in your calling shell.

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

arg 0: arg0, arg 1: arg1

Or escape the variables in your double-quoted string. Which to use might depend on exactly what you want to put in your snippet of code.

或者转义双引号字符串中的变量。使用哪个可能取决于您想要在代码片段中放入的内容。

回答by NawaMan

Because '$0' and '$1' in your string is replaced with a variable #0 and #1 respectively.

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

Try :

尝试 :

#!/bin/bash
echo 0:
$ bash -c './foo.sh ${1+"$@"}' foo "bar baz"
0:./foo.sh
1:bar baz
2:
echo 1: echo 2:

In this code $of both are escape so base see it as a string $and not get replaced.

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

The result of this command is:

这个命令的结果是:

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

Hope this helps.

希望这可以帮助。

回答by z0r

martin is right about the interpolation: you need to use single quotes. But note that if you're trying to pass arguments to a command that is being executed withinthe string, you need to forward them on explicitly. For example, if you have a script foo.shlike:

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

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

Then you should call it like this:

那么你应该这样称呼它

##代码##

Or more generally bash -c '${0} ${1+"$@"}' <command> [argument]...

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

Not like this:

不是这样的

##代码##

Nor like this:

也不像这样

##代码##

This means you can pass in arguments to sub-processes without embedding them in the command string, and without worrying about escaping them.

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

回答by tyranid

Add a backslash to the $0(i.e., \$0), otherwise your current shell escapes $0to the name of the shell before it even gets to the subshell.

$0(ie, \$0)添加一个反斜杠,否则你当前$0的 shell 会在它到达子 shell 之前转义到shell的名称。