$ _ vs!$。前面命令和输出重定向的最后一个参数


28

问题是关于特殊变量。文档说:

!!:$

指定前面命令最后一个参数。可以将其缩短为!$。


$_,下划线。)在shell启动时,设置为用于调用在环境或参数列表中传递的正在执行的shell或shell脚本的绝对路径名。随后,扩展到扩展后的上一个命令最后一个参数。还设置为用于调用每个执行的命令的完整路径名,并将其放置在导出到该命令的环境中。

我一定无法捕捉到一些差异,因为:

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

有什么不同?


4
$是历史扩展,不是特殊变量,因此我假设bash代码以不同的方式处理它们。
杰夫·谢勒

2
对于这个问题,我没有明确的答案,但是:①Bourne shell语言可能当今仍广泛使用的内部一致性最低的编程语言之一。试图推论一般原则将无济于事。您只需要记住所有特殊规则。抱歉。②在的定义中,在突出显示的短语之后立即注意单词“扩展后” $_。这很关键。它可能无法解释让您感到困惑的差异,但确实可以解释许多其他方式$_!$而且并不相同。
zwol

Answers:


32

!$是历史扩展的单词指示符,它扩展到历史上先前命令的最后一个单词。IOW,历史上先前输入的最后一个单词。这个词通常是命令的最后一个参数,但在重定向的情况下则不是。在:

echo "hello" > /tmp/a.txt

整个命令'echo "hello" > /tmp/a.txt'出现在历史上,并且/tmp/a.txt是该命令的最后一句话。

_是一个shell参数,它扩展为上一个命令的最后一个参数。此处,重定向不是传递给命令的参数的一部分,因此hello传递给的参数只有一部分echo。因此,$_扩展到hello

_不再是Shell标准的特殊参数之一。它仅适用于bash,和zshmksh并且dash仅在交互式ksh93时才能使用,并且仅在两个命令位于分隔行时才适用:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1

1
!$扩展vs $_参数的作用之一是,echo $_在历史记录中始终显示为echo $_,而echo !$将其扩展为显示的值。例如,echo one two然后echo !$,然后按了演出echo two
Jacktose
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.