反引号与双引号

反引号与双引号

这个问题我想了很久,但一直不知道怎么查

这是:

x=`command -v r2g`

与此相同:

x="$(command -v r2g)"

还是与此相同:

x=$(command -v r2g)

...如果是后者,我应该这样做来解决它吗?

x="`command -v r2g`"

答案1

所有示例都是来自命令替换的变量赋值,因此它们是等效的。按照吉尔斯的答案,在变量赋值的右侧不需要引用,因为那里不会发生分词。所以四个都OK。

如果它们是独立的,即不在作业中,那么您需要引用。与反引号相比,这种 $(...)形式的优点是引号可以嵌套并分成多行,这就是为什么现在普遍首选这种形式。换句话说,您可以"$( echo "$var" )" 使用此形式来保护 的内部扩展$var和外部扩展$(...)免受分词和文件名通配的影响。

如图所示POSIX Shell 命令语言根据规范,嵌入式多行脚本不能使用反引号(左侧),但可以使用$()表单(右侧)。

echo `                         echo $(
cat <<\eof                     cat <<\eof
a here-doc with `              a here-doc with )
eof                            eof
`                              )


echo `                         echo $(
echo abc # a comment with `    echo abc # a comment with )
`                              )


echo `                         echo $(
echo '`'                       echo ')'
`                              )

答案2

这四个示例在功能上是等效的。

反引号已经过时了,除非您使用 1970 年的 shell,如 Bourne shell(如 Heirloom),否则您不需要它们。主要问题是他们是很难筑巢, 尝试:

$ echo $(uname | $(echo cat))
Linux

$ echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

在只有一个赋值的命令行的右侧,没有必要(但无害)引用扩展,因为无论如何扩展都被认为是引用的:

$ var=$(uname)

但那就是不是始终为 true,命令导出上的赋值被视为参数,并将在某些 shell 中进行 split 和 glob(不是在 bash 中):

$ dash -c 'export MYVAR=`echo a test`;echo "$MYVAR"'
a

同样的推理适用于local(局部变量赋值需要引号吗?)和declare(以及其他一些)。

您应该做的“修复它”是:

x=$(command -v r2g)

有时(对于可移植脚本):

export x="$(command -v r2g)"

答案3

是的,反引号也应该被引用。

对于命令输出不包含空格的情况,这可能是首选 bash 样式的问题。以下是该实用程序作者的引述shellharden,摘自“如何在 bash 中安全地做事”:

Should I use backticks?
Command substitutions also come in this form:

Correct: "`cmd`"
Bad: `cmd`
While it is possible to use this style correctly, it looks even more awkward in quotes and is less readable when nested. The consensus around this one is pretty clear: Avoid.

Shellharden rewrites these into the dollar-parenthesis form.

我还相信用 引用反引号",或者(更好)重写它以使用 是很好的形式$()。如果使用反引号时命令输出包含空格或特殊字符,如果不引用表达式可能会出现问题。

答案4

是的,根据这份文件,我的猜测看起来是正确的: https://github.com/anordal/shellharden/blob/master/how_to_do_things_safely_in_bash.md

它说:

# Should I use backticks?
# Command substitutions also come in this form:

Correct: "`cmd`"
Bad: `cmd`

相关内容