Secondo il manuale di Bash , la variabile di ambiente BASH_COMMAND
contiene
Il comando attualmente in esecuzione o che sta per essere eseguito, a meno che la shell non stia eseguendo un comando come risultato di una trap, nel qual caso è il comando in esecuzione al momento della trap.
Prendendo da parte il caso dell'angolo trap, se ho capito bene questo significa che quando eseguo un comando, la variabile BASH_COMMAND
contiene quel comando. Non è assolutamente chiaro se quella variabile non sia impostata dopo l'esecuzione del comando (ovvero, è disponibile solo mentre il comando è in esecuzione, ma non dopo), anche se si potrebbe sostenere che poiché è "il comando attualmente in esecuzione o sta per essere eseguito" , non è il comando che è stato appena eseguito.
Ma controlliamo:
$ set | grep BASH_COMMAND=
$
Vuoto. Mi sarei aspettato di vedere BASH_COMMAND='set | grep BASH_COMMAND='
o forse solo BASH_COMMAND='set'
, ma il vuoto mi ha sorpreso.
Proviamo qualcos'altro:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
Beh, ha senso. Eseguo il comando echo $BASH_COMMAND
e quindi la variabile BASH_COMMAND
contiene la stringa echo $BASH_COMMAND
. Perché questa volta ha funzionato, ma non prima?
Facciamo di set
nuovo la cosa:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Quindi aspetta. È stato impostato quando ho eseguito quel echo
comando e in seguito non è stato disattivato. Ma quando ho eseguito di set
nuovo, BASH_COMMAND
non è stato impostato il set
comando. Non importa quante volte eseguo il set
comando qui, il risultato rimane lo stesso. Quindi, la variabile è impostata durante l'esecuzione echo
, ma non durante l'esecuzione set
? Vediamo.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Che cosa? Quindi la variabile è stata impostata al momento dell'esecuzione echo $BASH_COMMAND
, ma non al momento dell'esecuzione echo Hello AskUbuntu
? Dov'è la differenza adesso? La variabile è impostata solo quando l'attuale comando stesso impone effettivamente alla shell di valutare la variabile? Proviamo qualcosa di diverso. Forse un comando esterno questa volta, non un built-in bash, per cambiare.
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
Hmm, ok ... di nuovo, la variabile è stata impostata. Quindi la mia ipotesi attuale è corretta? La variabile è impostata solo quando deve essere valutata? Perché? Perché? Per motivi di prestazioni? Facciamo un altro tentativo. Cercheremo di eseguire grep $BASH_COMMAND
in un file, e poiché $BASH_COMMAND
quindi dovrebbe contenere un grep
comando, grep
dovrebbe grep per quel grep
comando (cioè, per se stesso). quindi facciamo un file appropriato:
$ 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 interessante. Il comando è grep $BASH_COMMAND tmp
stato espanso in grep grep $BASH_COMMAND tmp tmp
(la variabile si espande solo una volta, ovviamente), e quindi ho cercato grep
, una volta in un file $BASH_COMMAND
che non esiste e due volte nel file tmp
.
Q1: Il mio presupposto attuale è corretto che:
BASH_COMMAND
viene impostato solo quando un comando tenta di valutarlo effettivamente; e- esso è non disinserito dopo l'esecuzione di un comando, anche se la descrizione può portarci a credere così?
Q2: Se sì, perché? Prestazione? In caso negativo, in che altro modo è possibile spiegare il comportamento nella sequenza di comandi sopra?
Q3: Infine, esiste uno scenario in cui questa variabile potrebbe essere effettivamente utilizzata in modo significativo? In realtà stavo cercando di usarlo all'interno $PROMPT_COMMAND
per analizzare il comando in esecuzione (e fare alcune cose a seconda di quello), ma non posso, perché non appena, all'interno del mio $PROMPT_COMMAND
, eseguo un comando per guardare la variabile $BASH_COMMAND
, la variabile viene impostato su quel comando. Anche quando faccio MYVARIABLE=$BASH_COMMAND
bene all'inizio del mio $PROMPT_COMMAND
, allora MYVARIABLE
contiene la stringa MYVARIABLE=$BASH_COMMAND
, perché anche un compito è un comando. (Questa domanda non riguarda come ho potuto ottenere il comando corrente all'interno di $PROMPT_COMMAND
un'esecuzione. Ci sono altri modi, lo so.)
È un po 'come con il principio di incertezza di Heisenberg. Solo osservando la variabile, la cambio.
bash
über-guru lì.