$ _ vs! $. Letztes Argument des vorhergehenden Befehls und Ausgabeumleitung

28

Die Frage betrifft spezielle Variablen. Dokumentation sagt:

!!:$

bezeichnet das letzte Argument des vorhergehenden Befehls . Dies kann auf! $ Gekürzt werden.


( $_, ein Unterstrich.) Legen Sie beim Starten der Shell den absoluten Pfadnamen fest, der zum Aufrufen der Shell oder des Shell-Skripts verwendet wird, die bzw. das in der Umgebungs- oder Argumentliste übergeben wird. Anschließend wird nach der Erweiterung bis zum letzten Argument des vorherigen Befehls erweitert. Stellen Sie auch den vollständigen Pfadnamen ein, der zum Aufrufen aller ausgeführten und in die für diesen Befehl exportierte Umgebung platzierten Befehle verwendet wird.

Es muss einen Unterschied geben, den ich nicht fangen kann, weil:

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

Was ist der Unterschied?

Webstuhl
quelle
4
! $ ist eine History-Erweiterung, keine spezielle Variable, daher würde ich davon ausgehen, dass der Bash-Code sie anders behandelt.
Jeff Schaller
2
Ich habe keine definitive Antwort auf diese Frage, aber: ① Die Bourne-Shell-Sprache ist eine der vielleicht am wenigsten konsistenten Programmiersprachen, die heute noch weit verbreitet ist. Der Versuch, allgemeine Prinzipien abzuleiten, bringt Sie nicht weiter. Sie müssen nur alle Sonderregeln auswendig lernen. Es tut uns leid. ② Notieren Sie die Wörter "nach Erweiterung" unmittelbar nach der von Ihnen hervorgehobenen Phrase in der Definition von $_. Das ist entscheidend. Es erklärt vielleicht nicht den Unterschied, der Sie verwirrt, aber es erklärt eine Reihe anderer Möglichkeiten $_und !$ist nicht dasselbe.
zwol

Antworten:

32

!$ist ein Wortbezeichner für die Erweiterung der Geschichte. Es wird bis zum letzten Wort des vorherigen Befehls in der Geschichte erweitert . IOW, das letzte Wort des vorherigen Eintrags in der Geschichte. Dieses Wort ist normalerweise das letzte zu befehlende Argument, jedoch nicht im Falle einer Umleitung. Im:

echo "hello" > /tmp/a.txt

Der gesamte Befehl 'echo "hello" > /tmp/a.txt'erschien in der Geschichte und /tmp/a.txtist das letzte Wort dieses Befehls.

_ist ein Shell-Parameter, der bis zum letzten Argument des vorherigen Befehls erweitert wird. Hier ist die Umleitung kein Teil der Argumente, die an den Befehl übergeben werden, sondern nur hellodas Argument, an das übergeben wird echo. Deshalb $_erweitert um hello.

_ist nicht mehr einer der speziellen Shell-Standardparameter . Es funktioniert in bash, zsh, mkshund dashnur dann , wenn interaktiven, ksh93nur dann , wenn zwei Befehle sind auf getrennte Linien:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1
cuonglm
quelle
1
Ein Effekt von !$Expansion vs $_Parameter ist, dass echo $_in der Historie immer als angezeigt wird echo $_, während echo !$der Wert angezeigt wird, auf den es erweitert wurde. ZB echo one twodann echo !$dann hochdrücken zeigt echo two.
Jacktose