为什么 echo 被称为 /bin/sh -c echo foo 不输出任何内容?

为什么 echo 被称为 /bin/sh -c echo foo 不输出任何内容?

例如,虽然这有效:

$ 回声 foo

这不会:

$ /bin/sh -c 回显 foo

而这确实:

$ /bin/sh -c 'echo foo;回声酒吧'
酒吧

有解释吗?

答案1

man sh

-c string   If the -c option 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

这意味着你的命令应该是这样的:

 $ sh -c 'echo "$0"' foo 
 foo

相似地:

$ sh -c 'echo "$0 $1"' foo bar
foo bar

这是首先要理解的部分;我想第二种情况很简单,不需要解释。

答案2

$ echo foo
foo

echo与参数一起调用被打印。

$ /bin/sh -c echo foo

这将使用参数调用 shellecho并提供作为论证 $0。输出echo一个新行,然后您丢弃。如果你想输出,引用论证:

sh -c 'echo foo'

或使用提供的参数:

sh -c 'echo $0' foo

在这个例子中

$ /bin/sh -c 'echo foo; echo bar'
foo
bar

echo foo; echo bar使用输出参数调用 shell

foo
bar

答案3

在此命令中:

echo foo

echo是二进制文件(或内置命令),并且foo是第一个参数。

这里:

/bin/sh -c echo foo

/bin/sh是二进制文件,其第一个参数是-c,它本身接受“命令字符串”作为参数。这是echo在上面的例子中。然后还有第三个参数:foo这是 的参数/bin/sh,而不是 的参数echo。这就是为什么在你的第三个例子中:

/bin/sh -c 'echo foo; echo bar'

... 两者均已打印。你引用了这个论点。因此:第一个参数是-c,该参数的形参是'echo foo; echo bar'which 被整个解释为一个参数;作为“命令字符串”。

答案4

该结构sh -c word仅执行单词(在 shell 中)。
添加的单词表示其他含义,例如参数零、一、二等:

sh -c word zero one two three

要将包含空格的命令保留为一个单词,需要引用:

sh -c 'echo fnord' zero one two three

所以,这会打印所有参数:

$ sh -c 'echo "args=" "$0" "$@"' zero one two three
args = zero one two three

例子

在您提供的示例中:/bin/sh -c echo foo第一个单词(选项之后)是echo,这就是执行的内容。没有文本的 echo 只会打印换行符,不会打印其他内容:

$ /bin/sh -c 回显 foo

这就是为什么你会得到一个空行。

如果您引用空格,您将执行“一个单词”(无空格),如下所示:

$ /bin/sh -c echo\ foo
$ /bin/sh -c "echo foo"
$ /bin/sh -c 'echo foo'

结论

使用引号将执行的命令保留为一个“单词”。

相关内容