ähnlich wie das vorhandene $_
, das, wie ich gelernt habe, für steht !-1:$
, möchte ich Aliase für usw. erstellen $__
, $___
die sich auf den vorletzten oder drittletzten Befehl beziehen. Ich habe versucht, hinzuzufügen
alias "$__"='!-2:$'
in meinem .zshrc.local
. Wenn möglich, würde ich gerne eine Zsh-Funktion schreiben, die das 1. Argument des n-ten letzten Befehls basierend auf der Anzahl der Unterstriche zurückgibt.
arch linux kernel 5.1.4-arch
zsh 5.7.1 (x86_64-pc-linux-gnu)
Antwort1
Diese Funktionalität existiert bereits
Um auf das letzte Wort vorheriger Befehle zuzugreifen, müssen Sie nichts Kompliziertes tun. Drücken Sie einfach ESC-.
(ie Alt+ .) oder ESC-_
(ie Alt+ _). Dies ruft den Editorbefehl aufinsert-last-word
, wodurch das letzte Wort der vorherigen Befehlszeile eingefügt wird. Drücken Sie die Taste erneut, um das letzte Wort der vorherigen Befehlszeile zu erhalten, und so weiter. Wenn Sie ESC-.
einmal zu oft drücken, können Sie mit C-_
(Rückgängig) zum vorherigen Wort zurückkehren.
Dieser Befehl ist im vi-Modus standardmäßig nicht an eine Taste gebunden, Sie können ihn aber mit binden bindkey
.
Sie können ein numerisches Argument übergeben, um ein anderes Wort zu erhalten: positiv, um rechts zu beginnen (1 ist das letzte Wort), null oder negativ, um links zu beginnen (0 ist das erste Wort, das im Allgemeinen der Befehlsname ist, 1 ist das Wort danach, das das erste Argument ist usw.). Beispielsweise ESC . ESC - ESC 1 ESC .
fügt das erste Argument des vorletzten Befehls ein.
Viele Variationen dieses Befehls sind möglich, indem Sie Ihr eigenes Widget definieren zle insert-last-word
. Zsh kommt mitcopy-earlier-word
Undsmart-insert-last-word
die Sie entweder unverändert oder als Codebeispiele verwenden können.
Wenn Sie wirklich $__
bis zum letzten Wort des übervorherigen Befehls erweitern möchten, gebe ich unten einige Lösungen an, aber zuerst muss ich erklären, was passiert.
Warum Ihr Versuch nicht funktioniert
Erstens definieren Sie nicht das, was Sie zu definieren glauben. alias "$__"=…
definiert einen Alias, dessen Name der aktuelle Wert der Variable __
zum Zeitpunkt der Ausführung der Aliasdefinition ist. Dieser ist wahrscheinlich leer, also führen Sie aus, was nach einem Befehl sucht , der im Suchpfad alias ='!-2:$'
aufgerufen wird (der'!-2:$'
=
ErweiterungTeil der Dateinamenerweiterung). Um einen Alias mit dem Namen zu definieren $__
, müssen Sie ihn $__
an den Alias-Befehl übergeben, z. B. mit alias '$__'=…
oder alias \$__=…
.
Zweitens wird ein Alias nur in der Befehlsposition erweitert, also als erstes Wort eines Befehls (nach allen führenden Variablenzuweisungen und Umleitungen). Damit dieser Alias nützlich ist, müsste er einglobaler Alias:alias -g '$__'=…
Drittens würde dieser Alias nichts Nützliches bewirken, da die Alias-Erweiterung nach der Verlaufserweiterung erfolgt.
darkstar
darkstar% alias -g '$__'='!-2:$'
darkstar% echo $__
!-2:$
$_
steht nicht für !-1:$
. $_
und !-1:$
sind zwei Möglichkeiten, in häufigen Fällen auf dieselben Informationen zuzugreifen. Sie können sagen, dass $_
„ein Alias“ von ist !-1:$
, oder umgekehrt, dass !-1:$
„ein Alias“ von ist $_
, aber dabei wird „Alias“ im allgemeinen englischen Sinne verwendet, nicht im technischen Sinne von Shell-Aliasen, und es ist ungenau, da die beiden nicht immer denselben Wert haben. !-1:$
ist einGeschichte Erweiterung( !
) Konstrukt, das sich erweitert zumletztes Wort( :$
) desvorherige Befehlszeile( -1
). $_
ist einparameter expansion
mit dem Parameter_
den die Shell auf das letzte Argument des vorherigen Befehls setzt. Es macht einen Unterschied, wenn Sie Befehlszeilen ausführen, die nicht genau ein einfacher Befehl sind, zum Beispiel:
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
Definieren $__
pro Befehl
Sie können einenTrap-FunktionangerufenTRAPDEBUG
das vor der Ausführung jedes Befehls ausgeführt wird. Merken Sie sich den aktuellen Wert von $_
(beachten Sie, dass Sie dies zuerst tun müssen, da der erste Befehl im Trap überschreibt _
) und „verschieben“ Sie dann die Variablen mit mehreren Unterstrichen.
darkstar% TRAPDEBUG () { _0=$_; ___=$__; __=$_1; _1=$_0; }
darkstar% echo one
one
darkstar% echo two
two
darkstar% echo three
three
darkstar% echo $_,$__,$___
three,two,one
$_1
ist nicht immer dasselbe wie $_
, weil die Debug-Trap nicht unter genau denselben Umständen ausgeführt wird, die dazu führen, dass sie _
gesetzt wird, aber es kommt dem schon ziemlich nahe.
Definieren $__
per Kommandozeile
Sie können einHook-Funktionvor oder nach der Eingabe einer Befehlszeile ausgeführt werden. In diesem Fall entwederprecmd
oderpreexec
. Sie werden vor und nach der Ausführung eines Befehls ausgeführt.
preexec_set_underscore_variables () {
___=$__
__=$_1
_1=$historywords[1]
}
preexec_functions+=(preexec_set_underscore_variables)
ich benutzehistorywords
um das letzte Wort aus der Befehlszeile zu erhalten. Ich speichere es in, _1
weil _
es bereits vergeben ist. Und die Funktion „verschiebt“ die Variablen des letzten Wortverlaufs um eins.
darkstar% echo one
one
darkstar% echo two
two
darkstar% echo three
three
darkstar% echo $_ $__ $___
three two one