Laut Bash-HandbuchBASH_COMMAND
enthält die Umgebungsvariable
Der Befehl, der gerade ausgeführt wird oder gerade ausgeführt wird, es sei denn, die Shell führt einen Befehl als Ergebnis eines Traps aus. In diesem Fall handelt es sich um den Befehl, der zum Zeitpunkt des Traps ausgeführt wird.
Wenn ich den Fall der Trap-Ecke beiseite lasse, bedeutet dies, dass die Variable BASH_COMMAND
diesen Befehl enthält, wenn ich einen Befehl ausführe . Es ist nicht absolut klar, ob diese Variable nach der Befehlsausführung nicht gesetzt ist (dh nur verfügbar ist, während der Befehl ausgeführt wird, aber nicht danach), obwohl man argumentieren könnte, dass es sich um "den Befehl handelt, der gerade ausgeführt wird oder gerade ausgeführt wird". , es ist nicht der Befehl , der gerade ausgeführt wurde.
Aber lasst uns prüfen:
$ set | grep BASH_COMMAND=
$
Leeren. Ich hätte erwartet, zu sehen BASH_COMMAND='set | grep BASH_COMMAND='
oder vielleicht nur BASH_COMMAND='set'
, aber leer hat mich überrascht.
Versuchen wir etwas anderes:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
Na das macht Sinn. Ich führe den Befehl aus echo $BASH_COMMAND
und so BASH_COMMAND
enthält die Variable die Zeichenfolge echo $BASH_COMMAND
. Warum hat es diesmal funktioniert, aber nicht vorher?
Lass uns das set
Ding nochmal machen:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Also warte. Es wurde gesetzt, als ich diesen echo
Befehl ausführte , und es wurde danach nicht aufgehoben. Aber als ich set
nochmal ausführte , BASH_COMMAND
wurde nicht auf den set
Befehl gesetzt. Egal wie oft ich den set
Befehl hier ausführe , das Ergebnis bleibt gleich. Ist die Variable also beim Ausführen gesetzt echo
, aber nicht beim Ausführen set
? Wir werden sehen.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Was? Also wurde die Variable gesetzt, als ich ausgeführt habe echo $BASH_COMMAND
, aber nicht, als ich ausgeführt habe echo Hello AskUbuntu
? Wo ist jetzt der Unterschied? Wird die Variable nur gesetzt, wenn der aktuelle Befehl selbst die Shell zwingt, die Variable auszuwerten? Versuchen wir etwas anderes. Vielleicht ein externes Kommando, diesmal kein eingebauter Bash.
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
Hmm, ok ... wieder wurde die Variable gesetzt. Ist meine derzeitige Vermutung also richtig? Wird die Variable nur gesetzt, wenn sie ausgewertet werden muss? Warum? Warum? Aus Performancegründen? Versuchen wir es noch einmal. Wir werden versuchen, nach $BASH_COMMAND
in einer Datei zu suchen , und da $BASH_COMMAND
sollte dann ein grep
Befehl enthalten sein , grep
sollte nach diesem grep
Befehl gesucht werden (dh nach sich selbst). Machen wir also eine entsprechende Datei:
$ echo -e "1 foo\n2 grep\n3 bar\n4 grep \$BASH_COMMAND tmp" > tmp
$ grep $BASH_COMMAND tmp
grep: $BASH_COMMAND: No such file or directory
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
$ set | grep BASH_COMMAND=
BASH_COMMAND='grep --color=auto $BASH_COMMAND tmp'
$
Ok, interessant. Der Befehl grep $BASH_COMMAND tmp
wurde erweitert auf grep grep $BASH_COMMAND tmp tmp
(die Variable wird natürlich nur einmal erweitert), und so habe ich grep
einmal in einer Datei, $BASH_COMMAND
die nicht existiert, und zweimal in der Datei nachgegriffen tmp
.
F1: Ist meine derzeitige Annahme richtig, dass:
BASH_COMMAND
wird nur gesetzt, wenn ein Befehl versucht, ihn tatsächlich auszuwerten; und- Sie wird nach der Ausführung eines Befehls nicht deaktiviert, auch wenn die Beschreibung uns zu der Annahme verleitet.
Frage 2: Wenn ja, warum? Performance? Wenn nein, wie kann sonst das Verhalten in der obigen Befehlssequenz erklärt werden?
F3: Gibt es ein Szenario, in dem diese Variable tatsächlich sinnvoll verwendet werden könnte? Eigentlich habe ich versucht, $PROMPT_COMMAND
den ausgeführten Befehl damit zu analysieren (und davon abhängig einige Dinge zu tun), aber ich kann nicht, weil ich, sobald $PROMPT_COMMAND
ich einen Befehl ausführe $BASH_COMMAND
, der die Variable , die Variable, ansieht Ruft Sätze auf diesen Befehl ab. Auch wenn ich das MYVARIABLE=$BASH_COMMAND
gleich am Anfang mache $PROMPT_COMMAND
, dann MYVARIABLE
enthält der String MYVARIABLE=$BASH_COMMAND
, weil eine Zuweisung auch ein Befehl ist. (Bei dieser Frage geht es nicht darum, wie ich den aktuellen Befehl innerhalb einer $PROMPT_COMMAND
Ausführung erhalten kann. Ich weiß, dass es auch andere Möglichkeiten gibt.)
Es ist ein bisschen wie mit Heisenbergs Unschärferelation. Nur indem ich die Variable beobachte, ändere ich sie.
bash
Über-Gurus.