Verstehe die Bedeutung von `$ _`


10

Könnten Sie die folgenden Sätze aus dem Bash-Handbuch erklären $_, insbesondere die fett gedruckten Teile, vielleicht mit einigen Beispielen?

  1. Legen Sie beim Shell-Start den absoluten Pfadnamen fest, der zum Aufrufen der Shell oder des Shell-Skripts verwendet wird, die ausgeführt werden, wie in der Umgebungs- oder Argumentliste übergeben .

  2. Anschließend dehnt sich auf das letzte Argument des vorherigen Befehls, nach der Expansion.

  3. Stellen Sie auch den vollständigen Pfadnamen ein, der zum Aufrufen jedes ausgeführten und in die in diesen Befehl exportierte Umgebung platzierten Befehls verwendet wird .

  4. Beim Überprüfen von E-Mails enthält dieser Parameter den Namen der E-Mail-Datei.


4
-1 Frage unklar & nicht gründlich recherchiert. Was hast du versucht? Wo haben sich Ihre Erwartungen mit dem Text falsch ausgerichtet? Verstehst du das Wort "später" nicht ehrlich? Wenn ein neuer Benutzer dieselbe Frage stellen würde, hätte ich dieselben Fragen (trotz meiner ähnlichen angeborenen Neugier, wie genau die Dinge funktionieren).
Jeff Schaller

Antworten:


19

Ich bin damit einverstanden, dass es nicht sehr klar ist.

1. Beim Start der Shell

  • wenn die _Variable in der Umgebung war , die bashempfangen , dann bashlässt er unberührt.

    Insbesondere dann , wenn die bashSchale von einem anderen aufgerufen wurde bash Schal (obwohl zsh, yashund einige kshImplementierungen es auch tun), dann , dass bashwird Shell das Set - _Umgebungsvariable auf den Pfad des Befehls wird ausgeführt (die der dritte Punkt in Ihrer Frage ist). Wenn beispielsweise bashaufgerufen wird, um ein Skript als Ergebnis einer anderen bashShell-Interpretation zu interpretieren:

    bash-script some args

    Das bashist _=/path/to/bash-scripin der gegebenen Umgebung passiert bash-script, und das ist der Anfangswert der $_ bashVariablen in der bashShell, die dieses Skript interpretiert.

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
  • Nun, wenn die auslösende Anwendung kein Pass - _Umgebungsvariable , die geltend gemachte bashSchale wird initialisiert , $_um die argv[0]es sich erhält , welche sein könnte bash, oder /path/to/bashoder /path/to/some-scriptoder irgendetwas anderes (in dem obigen Beispiel, das wäre , /bin/bashwenn die sie Bang des Skripts war #! /bin/bash oder /path/to/bash-script abhängig vom System ).

    Dieser Text ist also irreführend, da er das Verhalten des Anrufers beschreibt, bashüber den er keine Kontrolle hat. Die aufgerufene Anwendung wird bashmöglicherweise überhaupt nicht festgelegt $_(in der Praxis tun execlp()dies beispielsweise nur einige Shells und einige seltene interaktive Anwendungen nicht), oder sie kann für etwas völlig anderes verwendet werden (z. B. ksh93setzt sie auf *pid*/path/to/command).

    $ env bash -c 'echo "$_"'
    /usr/bin/env   (env did not set it to /bin/bash, so the value we
                   get is the one passed to env by my interactive shell)
    $ ksh93 -c 'bash -c "echo \$_"'
    *20042*/bin/bash

2. Anschließend

Das Folgende ist auch nicht sehr klar. In der Praxis ist dies der Fall, sobald bashein einfacher Befehl in der aktuellen Shell-Umgebung interpretiert wird .

  • Im Fall einer interaktiven Shell wird dies beispielsweise beim ersten einfachen Befehl interpretiert /etc/bash.bashrc.

    Zum Beispiel an der Eingabeaufforderung einer interaktiven Shell:

     $ echo "$_"
     ]      (the last arg of the last command from my ~/.bashrc)
     $ f() { echo test; }
     $ echo "$_"
     ]      (the command-line before had no simple command, so we get
             the last argument of that previous echo commandline)
     $ (: test)
     $ echo "$_"
     ]      (simple command, but in a sub-shell environment)
     $ : test
     $ echo "$_"
     test
  • Bei einer nicht interaktiven Shell wäre dies der erste Befehl in $BASH_ENVoder des Codes, der dieser Shell zugeführt wird, wenn er $BASH_ENVnicht festgelegt ist.

3. Wenn Bash einen Befehl ausführt

Der dritte Punkt ist etwas anderes und wird in der obigen Diskussion angedeutet.

bashWie einige andere Shells übergeben sie eine _Umgebungsvariable an Befehle, die sie ausführen und die den Pfad enthalten, bashder als erstes Argument für die execve()Systemaufrufe verwendet wurde.

$ env | grep '^_'
_=/usr/bin/env

4. Beim Abrufen von E-Mails

Der vierte Punkt wird in der Beschreibung der MAILPATHVariablen ausführlicher beschrieben :

"MAILPATH"

Eine durch Doppelpunkte getrennte Liste von Dateinamen, die die Shell regelmäßig auf neue E-Mails überprüft .

Jeder Listeneintrag kann die Nachricht angeben, die gedruckt wird, wenn neue E-Mails in der E-Mail-Datei eingehen, indem der Dateiname von der Nachricht mit einem '?' Getrennt wird. Bei Verwendung im Nachrichtentext wird '$ _' auf den Namen der aktuellen Mail-Datei erweitert.

Beispiel:

$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>

3

Versuchen Sie dieses einfache Beispiel:

echo "$_"
echo "test"
echo "$_"

Führen Sie es aus, indem Sie den absoluten Pfad ( /home/$USERNAME/test.sh) angeben. Ausgabe:

/home/$USERNAME/test.sh
test
test

Der erste $_enthält den Pfad, den Sie zum Aufrufen des Skripts verwendet haben, und der zweite enthält das erste Argument in der Mitte echo. Wenn Sie für das dritte Element in der Liste ein neues Terminal starten und echo eingeben, $_ wird die Variable angezeigt, die PATHdas enthält, das normalerweise zum Nachschlagen und Aufrufen von Befehlen (auf meinem Ubuntu-Computer) in einer normalen Shell oder einem absoluten Pfad zu Ihrer .bashrsDatei in verwendet wird eine Login-Shell.

Für den Punkt vier aus der Bash-Manpage:

Wird im Text der Nachricht verwendet und wird $_auf den Namen der aktuellen Mail-Datei erweitert.


Vielen Dank. (1) Können Sie den dritten Fall anhand von Beispielen erklären? (2) Wenn ich einen neuen GNOME - Terminal Tab zu öffnen, die Ausgabe echo $_heißt EDITOR, und warum ist es? Welchem ​​Fall folgt es? (3) Können Sie ein Beispiel geben, wie Sie E-Mails abrufen und $_in diesem Fall verwenden?
Tim

Öffnen Sie Ihre .bashrcund kommentieren Sie dort jede Zeile aus. Behalten Sie nur eine einzelne Zeile bei, die einen Befehl wie echo "test"oder ähnlich enthält. Speichern und schließen. Dann laufen bashund sofort echo $_. Dieses letzte Echo sollte den Test in der Ausgabe drucken.
Kaffee Tasse

Für den Mail-Teil habe ich keine Unix-Mail verwendet und auf meinem System ist derzeit keine funktionierende Mail installiert. Daher kann ich Ihnen kein Beispiel geben. Sollte aber offensichtlich sein, wenn Sie der Beschreibung MAILPATHin linuxcommand.org/lc3_man_pages/bash1.html
coffeMug

1
Zu Ihrer Information , die kanonische, aktuelle Version des Bash-Handbuchs lautet: gnu.org/software/bash/manual/bashref.html . Es ist Version 4.3, während die Linux-Befehlsseite 4.1 war.
Jeff Schaller

1

Für Fall 2 sagt ein Beispiel mehr als tausend Worte:

mkdir my_long_dir
cd $_

Tut, was Sie erraten / hoffen würden. Gibt mir einen einfachen Platzhalter, wenn ich in der Befehlszeile bin, damit ich mich nicht wiederholen muss.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.