问题是关于特殊变量。文档说:
!!:$
指定前面命令的最后一个参数。这可以缩短为
!$
。
(
$_
,下划线。)在 shell 启动时,设置为用于调用在环境或参数列表中传递的 shell 或正在执行的 shell 脚本的绝对路径名。随后,扩展到上一个命令的最后一个参数扩建后。还设置为用于调用执行的每个命令并放置在导出到该命令的环境中的完整路径名。
一定有一些我无法捕捉到的差异,因为:
$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt
$ echo "hello" > /tmp/a.txt
$ echo $_
hello
有什么不同?
答案1
!$
是历史扩展的词指示符;它扩展到前一个命令的最后一个字历史。换句话说,历史上前一个条目的最后一个词。该词通常是命令的最后一个参数,但在重定向的情况下则不然。在:
echo "hello" > /tmp/a.txt
整个命令'echo "hello" > /tmp/a.txt'
出现在历史中,并且/tmp/a.txt
是该命令的最后一句话。
_
是一个 shell 参数;它扩展到上一个命令的最后一个参数。在这里,重定向不是传递给命令的参数的一部分,因此仅hello
传递给echo
.这就是为什么$_
扩展到hello
.
_
不再是其中之一外壳标准特殊参数。它仅在交互式时,仅当两个命令位于分隔行时才适用于bash
、zsh
、mksh
和:dash
ksh93
$ echo 1 && echo $_
1
/usr/bin/ksh
$ echo 1
1
$ echo $_
1
答案2
我发现直接使用参数替换即使不是不可能也是很困难的!$
。
例如,如果我可以wget http://foo.com/my.tar
,tar xf ${_##*/}
但如果!$
不定义中间变量,这是不可能的。