Ubuntu – La variable $ BASH_COMMAND convient pour

Selon le manuel de Bash, la variable d’environnement BASH_COMMAND contient

La commande en cours d’exécution ou sur le point d’être exécutée, sauf si le shell exécute une commande à la suite d’une interruption, auquel cas c’est la commande qui s’exécute au moment de l’interruption.

En prenant ce cas de coin de piège de côté, si je comprends bien, cela signifie que lorsque j’exécute une commande, la variable BASH_COMMAND contient cette commande. Il n’est pas absolument clair si cette variable n’est pas définie après l’exécution de la commande (c’est-à-dire qu’elle n’est disponible quetandis quela commande est en cours d’exécution, mais pas après), bien que l’on puisse affirmer qu’il s’agit de «la commandeactuellementen cours d’exécution ousur le point d’êtreexécuté « , ce n’est pas la commandec’était justeréalisé.

Mais vérifions:

 $ set | grep BASH_COMMAND=
$ 
 

Vide. Je m’attendais à voir BASH_COMMAND='set | grep BASH_COMMAND=' ou peut-être juste BASH_COMMAND='set' , mais vide m’a surpris.

Essayons autre chose:

 $ echo $BASH_COMMAND
echo $BASH_COMMAND
$ 
 

Eh bien, cela a du sens. J’exécute la commande echo $BASH_COMMAND et donc la variable BASH_COMMAND contient la chaîne echo $BASH_COMMAND . Pourquoi cela a-t-il fonctionné cette fois, mais pas avant?

Faisons le set chose encore:

 $ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
 

Alors attend. Ilétaitdéfinir quand je l’ai exécuté echo commande, etn’était pasdésarmé par la suite. Mais quand j’ai exécuté set encore, BASH_COMMAND  n’était pasréglé sur set commander. Peu importe la fréquence à laquelle j’exécute set commande ici, le résultat reste le même. Donc, est la variable définie lors de l’exécution echo , mais pas lors de l’exécution set ? Voyons voir.

 $ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
 

Quoi?Donc, la variable a été définie lorsque j’ai exécuté echo $BASH_COMMAND , maisne pasquand j’ai exécuté echo Hello AskUbuntu ? Où est la différence maintenant? La variable n’est-elle définie que lorsque la commande actuelle elle-même force réellement le shell à évaluer la variable? Essayons quelque chose de différent. Peut-être une commande externe cette fois, pas une commande bash intégrée, pour un changement.

 $ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
 

Hmm, ok… encore une fois, la variable a été définie. Alors, ma supposition actuelle est-elle correcte? La variable n’est-elle définie que lorsqu’elle doit être évaluée? Pourquoi?Pourquoi?Pour des raisons de performances? Faisons encore un essai. Nous essaierons de chercher $BASH_COMMAND dans un fichier, et depuis $BASH_COMMAND doit alors contenir un grep commander, grep devrait grep pour cela grep (c’est-à-dire pour lui-même). faisons donc un fichier approprié:

 $ 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, intéressant. La commande grep $BASH_COMMAND tmp a été étendu à grep grep $BASH_COMMAND tmp tmp (la variable est développée juste une fois, bien sûr), et j’ai donc cherché grep , une fois dans un fichier $BASH_COMMAND qui n’existe pas, et deux fois dans le fichier tmp .

Q1:Mon hypothèse actuelle est-elle correcte:

  •  BASH_COMMAND n’est définie que lorsqu’une commande essaie de l’évaluer; et
  • c’estne pasnon défini après l’exécution d’une commande, même si la description peut nous le faire croire?

Q2:Si oui, pourquoi? Performance? Si non, comment expliquer autrement le comportement dans la séquence de commandes ci-dessus?

Q3:Enfin, existe-t-il un scénario dans lequel cette variable pourrait réellement être utilisée de manière significative? J’essayais vraiment de l’utiliser dans $PROMPT_COMMAND d’analyser la commande en cours d’exécution (et de faire des choses en fonction de cela), mais je ne peux pas, car dès que, dans mon $PROMPT_COMMAND , J’exécute une commande pour regarder la variable $BASH_COMMAND , la variable obtient des ensembles pour cette commande. Même quand je le fais MYVARIABLE=$BASH_COMMAND juste au début de mon $PROMPT_COMMAND , puis MYVARIABLE contient la chaîne MYVARIABLE=$BASH_COMMAND , car une affectation est également une commande. (Cette question ne concerne pas la façon dont je pourrais obtenir la commande actuelle dans un $PROMPT_COMMAND exécution. Il y a d’autres façons, je sais.)

C’est un peu comme avec le principe d’incertitude de Heisenberg. Juste en observant la variable, je la change.

Meilleure réponse

  • Répondre à la troisième question: bien sûr, il peut être utilisé de manière significative dans la façon dont le manuel Bash laisse clairement entendre – dans un piège, e. g.:

     $ trap 'echo ‘$BASH_COMMAND’ failed with error code $?' ERR
    $ fgfdjsa
    fgfdjsa: command not found
    ‘fgfdjsa’ failed with error code 127
    $ cat /etc/fgfdjsa
    cat: /etc/fgfdjsa: No such file or directory
    ‘cat /etc/fgfdjsa’ failed with error code 1