了解反引号(`)


35

我正在尝试命令

$ b=5; echo `$b`;
-bash: 5: command not found

但它不会按预期打印5。我在这里想念什么?

命令中的`(反引号/反引号)是什么意思?似乎说可以`评估其中的命令并将其替换为输出。


8
请注意,不建议使用反引号,因为您将失去执行嵌套执行替换的功能。Insetad,首选$(somecommand)。恕我直言,它提高了可读性。
汤米2012年

6
@Tommy,不,反引号可以嵌套,但它成为逃避现实的噩梦,尤其是在双引号中。
斯特凡Chazelas

Answers:


52

反引号之间的文本将被执行,并由命令的输出替换(减去尾随的换行符,请注意,当输出中包含NUL字符时,shell行为会有所不同)。这被称为命令替换,因为它被命令的输出替换。因此,如果要打印5,则不能使用反引号,可以使用引号,例如,echo "$b"或仅删除任何引号并使用echo $b

如您所见,由于$b包含5,因此在使用反引号时bash尝试运行命令,5并且由于没有此类命令,因此失败并显示错误消息。

要了解反引号的工作原理,请尝试运行以下命令:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1应该打印/etc/passwd文件的第一行。但是由于我们使用反引号,因此不会在控制台上打印。而是将其存储在A变量中。您可以$A对此作出回应。注意,打印第一行的更有效方法是使用命令,head -n1 /etc/passwd但我想指出的是,反引号内的表达式不必很简单。

因此,如果/ etc / passwd的root:x:0:0:root:/root:/bin/bash第一行为,则bash将动态替换first命令为A="root:x:0:0:root:/root:/bin/bash"

请注意,此语法属于Bourne shell。报价和转义迅速成为噩梦,尤其是当您开始嵌套它们时。Ksh引入了$(...)现在已经标准化的替代方案(POSIX),并且所有外壳程序(甚至是Unix v9的Bourne外壳程序)都支持它。因此,$(...)除非您需要将其移植到非常旧的Bourne外壳,否则现在应该使用它代替。

还要注意的是输出`...`$(...)受到分词和文件名生成就像变扩建(在zsh中,分词只),所以一般都需要在列表上下文被引用。


1
@Krzysztof,您好!“因为$ b包含5,bash试图运行命令5”正是我所要的
coolcric 2012年

you can use quotation marks, like echo "$b"=>“”有什么特别之处吗?似乎echo $b同样有效。
Tootsie Rolls

@Anita:通常引号会做一些特殊的事情(它改变了特殊字符的处理方式-尤其是空格),但是在这种情况下,可以将它们删除而不会出现太大问题。这是因为没有使用特殊字符,并且echo命令不关心它获取的参数数量,因此如果b内部有空格,它将获得多个参数并仍将其打印出来。其他命令可能不是这种情况(尤其是在未设置变量的情况下),因此我倾向于总是用引号将变量引起来。
Krzysztof Adamski 2013年

如果(POSIX)可以链接到实际标准,那将很好。
erikbwork,2015年

1
@ erikb85:我未添加此注释,但我已按照您的建议通过链接对其进行了编辑:)
Krzysztof Adamski 2015年

11

反引号完全按照您说的去做。您已将变量设置为整数。当您将该变量放入反引号中时,bash会尝试将其作为命令执行。由于这不是命令,因此您会看到错误。

您要做的只是:

$ b=5; echo $b

要更好地理解反引号,请与以下内容进行比较:

$ b=5; a=`echo $b`; echo $a
  5

8

逐步讲解您的路线。

$ b=5; echo `$b`;
  1. 将变量设置b为5
  2. 评估$b(有效运行5
  3. echo是上面评估的输出。

是的,您得到的输出是预期的。您正在评估变量的内容,而不是您认为的实际命令。您放入反引号中的所有内容都会在新的(子)shell中进行simplay评估(运行)。


嗨@gertvdijk,谢谢你的帖子!我以为`在评估其内容后会返回剩下的所有内容。因此,我认为`$ b'将返回5以进行回显以打印出来
coolcric 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.