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 il s'agit de la commande en cours d'exécution 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 que lorsque la commande est en cours d'exécution, mais pas après), bien que l'on puisse dire que puisque c'est "la commande en cours d'exécution ou sur le point d'être exécutée" , ce n'est pas la commande qui vient d'être exécutée.
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 le 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 à set
nouveau la chose:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Alors attend. Il a été défini lorsque j'ai exécuté cette echo
commande, et il n'a pas été annulé par la suite. Mais lorsque j'ai exécuté à set
nouveau, la commande BASH_COMMAND
n'a pas été définie set
. Quelle que soit la fréquence d'exécution de la set
commande ici, le résultat reste le même. Donc, la variable est-elle 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'
$
Quelle? La variable a donc été définie lors de mon exécution echo $BASH_COMMAND
, mais pas lors de mon exécution 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 allons essayer de grep pour $BASH_COMMAND
dans un fichier, et puisque $BASH_COMMAND
devrait alors contenir une grep
commande, grep
devrait grep pour cette grep
commande (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 a grep $BASH_COMMAND tmp
été étendue à grep grep $BASH_COMMAND tmp tmp
(la variable n'est développée qu'une seule fois, bien sûr), et j'ai donc recherché 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- il n'est pas instable après 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 en fait de l'utiliser à l'intérieur $PROMPT_COMMAND
pour analyser la commande en cours d'exécution (et 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 à cette commande. Même lorsque je fais MYVARIABLE=$BASH_COMMAND
juste au début de mon $PROMPT_COMMAND
, MYVARIABLE
contient alors la chaîne MYVARIABLE=$BASH_COMMAND
, car une affectation est aussi une commande. (Cette question ne porte pas sur la façon dont je pourrais obtenir la commande actuelle dans une $PROMPT_COMMAND
exécution. Il existe d'autres moyens, je sais.)
C'est un peu comme avec le principe d'incertitude de Heisenberg. Juste en observant la variable, je la change.
bash
über-gourous là-bas.