為歷史擴展模式設置別名
類似於我所
$_
學的現有代表!-1:$
,我想為 , 等創建別名$__
,$___
以引用第二個或第三個 -last 命令。我試過添加alias "$__"='!-2:$'
在我的
.zshrc.local
. 如果可能的話,我想寫一個 zsh 函式,它根據下劃線的數量返回第 n 個最後一個命令的第一個參數。arch linux kernel 5.1.4-arch zsh 5.7.1 (x86_64-pc-linux-gnu)
此功能已存在
您不需要任何復雜的東西來訪問先前命令的最後一個字。只需按
ESC-.
(ieAlt
+.
) 或ESC-_
(ieAlt
+_
)。這會呼叫編輯器命令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 '$__'=…
第三,這個別名不會做任何有用的事情,因為別名擴展發生在歷史擴展之後。
darkstar darkstar% alias -g '$__'='!-2:$' darkstar% echo $__ !-2:$
$_
不“代表”!-1:$
。$_
並且!-1:$
是在常見情況下訪問相同資訊的兩種方式。你可以說$_
“是 的別名”!-1:$
,或者反過來說!-1:$
“是 的別名”$_
,但這是在一般英語意義上使用“別名”,而不是在 shell 別名的技術意義上使用,而且不精確,因為兩者都沒有t 始終具有相同的值。!-1:$
是一個歷史擴展(!
) 構造,它擴展到前一個命令行( ) 的最後一個單詞(:$
) 。是一個使用參數-1``$_
parameter expansion
_
shell 將其設置為前一個命令的最後一個參數。如果您執行的命令行不完全是一個簡單的命令,則會有所不同,例如: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
定義
$__
每個命令您可以定義一個稱為陷阱函式
TRAPDEBUG
,該函式在執行每個命令之前執行。記住 的目前值$_
(請注意,您必須先執行此操作,因為陷阱內的第一個命令將覆蓋_
),然後“移位”多個下劃線變數。darkstar% TRAPDEBUG () { _0=$_; ___=$__; __=$_1; _1=$_0; } darkstar% echo one one darkstar% echo two two darkstar% echo three three darkstar% echo $_,$__,$___ three,two,one
$_1
不會總是與 相同$_
,因為調試陷阱不會在導致_
設置的完全相同的情況下執行,但它非常接近。定義
$__
每個命令行您可以註冊一個鉤子函式以在輸入命令行之前或之後執行。在這種情況下,要麼
precmd
要麼preexec
。它們分別在執行命令之前和之後執行。preexec_set_underscore_variables () { ___=$__ __=$_1 _1=$historywords[1] } preexec_functions+=(preexec_set_underscore_variables)
我用來
historywords
從命令行獲取最後一個單詞。我把它存起來,_1
因為_
已經被拿走了。並且該函式將最後一個單詞的歷史變數“移動”一個。darkstar% echo one one darkstar% echo two two darkstar% echo three three darkstar% echo $_ $__ $___ three two one