我正在尝试I say "Hello, World!"
与bash -c
. 这是(部分)我尝试过的:
$ bash -c "echo I say \"Hello, World"'!'"\""
$ bash -c "echo I say "'"'"Hello, World"'!'"\""
$ bash -c "echo I say """Hello, World"""'!'
$ bash -c $'echo I say \"Hello, World!\"'
$ bash -c 'echo I say "Hello, World!"'
他们都打印
I say Hello, World!
我怎样才能显示报价?
问题在于你有嵌套的引号,这使得引用有点复杂。由于您没有围绕您的论点的“全面”引号,因此您的
echo
所有尝试(除了您的第三次尝试(1))实际上都将三个参数传递给echo
,它们都需要删除引号:I
say
Hello, World!
关键是在解释“外部”命令时,要
bash -c
删除参数的外部引号。内部引号保留下来,要么是因为它们被转义了,要么是因为它们与外部引号的类型不同。然后,当
bash
您显式调用的实例处理该参数(“内部”命令)时,它本身会在解释调用参数时执行引号删除echo
。因此,您放置的引号Hello, World!
将确保 this 被视为 的一个参数echo
,但会在同一过程中被删除(从而丢失给echo
)。由于您不需要在 ("inner")
echo
命令中进行变量扩展,因此我会使用单引号语法,如下所示:这样您就将一个参数传递给
echo
,并且双引号内的引号转义将按预期工作。(1)在您展示的第三次尝试中,您实际上是将 2 个参数传递给
bash -c
:echo I say Hello,
和World!
导致“内部”命令看到的四个参数。
echo
这是因为您尝试用这种方式“中断”外部双引号"""
不起作用 - 相反,这些双引号中的第一个意味着bash -c
参数的起始双引号在空格之后关闭。然后这被视为后面跟着一个空的双引号字符串,然后是一个不带引号Hello,
的. 所有这些都是串联的,因为它们之间没有空格。然后,由于后面的空格不受保护,外部
bash
现在将剩余部分视为第二个参数,从(再次未加引号)开始World
,一个双引号空字符串,然后是一个打开但未关闭的双引号字符串,其中包含'!'
。它没有正确关闭的事实被你应该收到的关于“找不到事件”的错误消息所掩盖,因为开始的双引号使后面的单引号只是一个要打印的字符,因此!
没有不再被解释为历史参考。如果您不关心 POSIX 合规性,您可以通过添加和打印 ascii 代码(十六进制)或(八进制)
-e
来解决这个问题。echo
"
\x22
\042
bash -c 'echo -e "I say \x22Hello, World\x22"'
bash -c 'echo -e "I say \042Hello, World\042"'