darkstar% for x in 1 2 3; do echo $x; done
1
2
3
darkstar% echo $_ is not !-1:$
echo $_ is not done
3 is not done
darkstar% echo $_ and !-1:$ are different; echo $_ and !-1:$ are different
echo $_ and done are different; echo $_ and done are different
done and done are different
different and done are different
darkstar% TRAPDEBUG () { _0=$_; ___=$__; __=$_1; _1=$_0; }
darkstar% echo one
one
darkstar% echo two
two
darkstar% echo three
three
darkstar% echo $_,$__,$___
three,two,one
此功能已存在
您不需要任何复杂的东西来访问先前命令的最后一个字。只需按
ESC-.
(ie Alt+ .) 或ESC-_
(ie Alt+ _)。这会调用编辑器命令insert-last-word
,该命令会插入前一个命令行的最后一个单词。再次按该键以从命令行获取最后一个单词,依此类推。如果按ESC-.
一次太多,请使用C-_
(撤消)返回到之前的单词。此命令在 vi 模式下默认不绑定到键,但您可以将其绑定到
bindkey
.您可以传递一个数字参数来获取不同的单词:从右侧开始的正数(1 是最后一个单词),从左侧开始的零或负数(0 是第一个单词,通常是命令名称,1 是在第一个参数之后的单词等)。例如
ESC . ESC - ESC 1 ESC .
插入倒数第二个命令的第一个参数。通过在
zle insert-last-word
. Zsh 附带copy-earlier-word
,smart-insert-last-word
您可能会发现它对按原样使用或作为代码示例很有用。如果你真的想
$__
扩展到previous-but-one命令的最后一个单词,我会在下面给出一些解决方案,但首先我需要解释一下发生了什么。为什么您的尝试不起作用
首先,你没有定义你认为你定义的东西。定义一个别名,其名称是执行别名定义时
alias "$__"=…
变量的当前值。__
这可能是空的,因此您正在执行查找在搜索路径(文件名扩展的扩展部分)上alias ='!-2:$'
调用的命令。要定义一个名为 的别名,您需要传递给 alias 命令,例如 with或。'!-2:$'
=
$__
$__
alias '$__'=…
alias \$__=…
其次,别名仅在命令位置扩展,即作为命令的第一个字(在任何前导变量分配和重定向之后)。为了使这个别名有用,它需要是一个全局别名:
alias -g '$__'=…
第三,这个别名不会做任何有用的事情,因为别名扩展发生在历史扩展之后。
$_
不“代表”!-1:$
。$_
并且!-1:$
是在常见情况下访问相同信息的两种方式。你可以说$_
“是 的别名”!-1:$
,或者反过来说!-1:$
“是 的别名”$_
,但这是在一般英语意义上使用“别名”,而不是在 shell 别名的技术意义上使用,而且不精确,因为两者都没有t 始终具有相同的值。!-1:$
是一个历史扩展(!
) 构造,它扩展到前一个命令行( ) 的最后一个单词(:$
) 。是一个使用参数-1
$_
parameter expansion
_
shell 将其设置为前一个命令的最后一个参数。如果您运行的命令行不完全是一个简单的命令,则会有所不同,例如:定义
$__
每个命令您可以定义一个称为陷阱函数
TRAPDEBUG
,该函数在执行每个命令之前运行。记住 的当前值$_
(请注意,您必须先执行此操作,因为陷阱内的第一个命令将覆盖_
),然后“移位”多个下划线变量。$_1
不会总是与 相同$_
,因为调试陷阱不会在导致_
设置的完全相同的情况下运行,但它非常接近。定义
$__
每个命令行您可以注册一个钩子函数以在输入命令行之前或之后运行。在这种情况下,要么
precmd
要么preexec
。它们分别在执行命令之前和之后运行。我用来
historywords
从命令行获取最后一个单词。我把它存起来,_1
因为_
已经被拿走了。并且该函数将最后一个单词的历史变量“移动”一个。