Secondo il manuale di Bash , la variabile di ambiente BASH_COMMANDcontiene
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_COMMANDcontiene 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_COMMANDe quindi la variabile BASH_COMMANDcontiene la stringa echo $BASH_COMMAND. Perché questa volta ha funzionato, ma non prima?
Facciamo di setnuovo la cosa:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Quindi aspetta. È stato impostato quando ho eseguito quel echocomando e in seguito non è stato disattivato. Ma quando ho eseguito di setnuovo, BASH_COMMAND non è stato impostato il setcomando. Non importa quante volte eseguo il setcomando 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_COMMANDin un file, e poiché $BASH_COMMANDquindi dovrebbe contenere un grepcomando, grepdovrebbe grep per quel grepcomando (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 tmpstato 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_COMMANDche non esiste e due volte nel file tmp.
Q1: Il mio presupposto attuale è corretto che:
BASH_COMMANDviene 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_COMMANDper 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_COMMANDbene all'inizio del mio $PROMPT_COMMAND, allora MYVARIABLEcontiene 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_COMMANDun'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ì.