Zgodnie z instrukcją Bash zmienna środowiskowa BASH_COMMANDzawiera
Komenda aktualnie wykonywana lub planowana do wykonania, chyba że powłoka wykonuje komendę w wyniku pułapki, w którym to przypadku jest to komenda wykonywana w chwili pułapki.
Pomijając tę narożną wielkość liter, jeśli dobrze rozumiem, oznacza to, że kiedy wykonuję polecenie, zmienna BASH_COMMANDzawiera to polecenie. Nie jest absolutnie jasne, czy zmienna ta jest rozbrojona po wykonaniu polecenia (tj. Jest dostępna tylko podczas wykonywania polecenia, ale nie później), choć można argumentować, że ponieważ jest to „polecenie aktualnie wykonywane lub wkrótce wykonywane” , to nie polecenie zostało właśnie wykonane.
Ale sprawdźmy:
$ set | grep BASH_COMMAND=
$
Pusty. Spodziewałbym się zobaczyć, BASH_COMMAND='set | grep BASH_COMMAND='a może po prostu BASH_COMMAND='set', ale pusty mnie zaskoczył.
Spróbujmy czegoś innego:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
To ma sens. Wykonuję polecenie, echo $BASH_COMMANDwięc zmienna BASH_COMMANDzawiera ciąg echo $BASH_COMMAND. Dlaczego tym razem zadziałało, ale nie wcześniej?
Zróbmy to jeszcze setraz:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Więc poczekaj. To było ustawione, że kiedy wykonywane echopolecenie, a on nie był wyłączony później. Ale kiedy wykonałem setponownie, BASH_COMMAND nie został ustawiony na setpolecenie. Bez względu na to, jak często wykonuję setpolecenie tutaj, wynik pozostaje taki sam. Czy zmienna jest ustawiona podczas wykonywania echo, ale nie podczas wykonywania set? Zobaczmy.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Co? Więc zmienna została ustawiona, kiedy wykonałem echo $BASH_COMMAND, ale nie kiedy wykonałem echo Hello AskUbuntu? Jaka jest teraz różnica? Czy zmienna jest ustawiona tylko wtedy, gdy bieżące polecenie faktycznie zmusza powłokę do oceny zmiennej? Spróbujmy czegoś innego. Może tym razem jakieś zewnętrzne polecenie, a nie wbudowane bash, dla odmiany.
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
Hmm, ok ... znowu, zmienna została ustawiona. Czy moje obecne przypuszczenie jest prawidłowe? Czy zmienna jest ustawiana tylko wtedy, gdy należy ją ocenić? Czemu? Czemu? Z powodów wydajnościowych? Spróbujmy jeszcze raz. Spróbujemy grepować $BASH_COMMANDw pliku, a ponieważ $BASH_COMMANDpowinien zawierać greppolecenie, greppowinien grep dla tego greppolecenia (tj. Dla siebie). więc stwórzmy odpowiedni plik:
$ 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, ciekawe. Polecenie grep $BASH_COMMAND tmpzostało rozszerzone do grep grep $BASH_COMMAND tmp tmp(zmienna jest rozwinięta tylko raz, oczywiście), więc poszukałem grep, raz w pliku, $BASH_COMMANDktóry nie istnieje, i dwa razy w pliku tmp.
P1: Czy moje obecne założenie jest prawidłowe, że:
BASH_COMMANDjest ustawiany tylko wtedy, gdy polecenie próbuje to ocenić; i- to jest nie rozbroić po wykonaniu polecenia, choć opis może doprowadzić nas do przekonania, tak?
P2: Jeśli tak, dlaczego? Wydajność? Jeśli nie, jak inaczej można wyjaśnić zachowanie w powyższej sekwencji poleceń?
P3: Na koniec, czy jest jakiś scenariusz, w którym ta zmienna mogłaby być rzeczywiście użytecznie użyta? W rzeczywistości próbowałem użyć go w $PROMPT_COMMANDcelu przeanalizowania wykonywanego polecenia (i zrobić kilka rzeczy w zależności od tego), ale nie mogę, ponieważ jak tylko $PROMPT_COMMANDwykonam wewnątrz siebie polecenie, aby spojrzeć na zmienną $BASH_COMMAND, zmienną pobiera zestawy do tego polecenia. Nawet jeśli robię to MYVARIABLE=$BASH_COMMANDna samym początku $PROMPT_COMMAND, MYVARIABLEzawiera ciąg MYVARIABLE=$BASH_COMMAND, ponieważ przypisanie jest również poleceniem. (To pytanie nie dotyczy tego, w jaki sposób mogę uzyskać bieżące polecenie w ramach $PROMPT_COMMANDwykonania. Wiem, że istnieją inne sposoby).
To trochę tak, jak w przypadku zasady nieoznaczoności Heisenberga. Po prostu obserwując zmienną, zmieniam ją.
bashguru über-guru.