Einrichten von Aliasnamen für ein Verlaufserweiterungsmuster

Einrichten von Aliasnamen für ein Verlaufserweiterungsmuster

ä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-wordUndsmart-insert-last-worddie 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 expansionmit 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-FunktionangerufenTRAPDEBUGdas 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

$_1ist 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 entwederprecmdoderpreexec. 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 benutzehistorywordsum das letzte Wort aus der Befehlszeile zu erhalten. Ich speichere es in, _1weil _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

verwandte Informationen