De acordo com o manual de Bash , a variável de ambiente BASH_COMMAND
contém
O comando atualmente sendo executado ou prestes a ser executado, a menos que o shell esteja executando um comando como resultado de um trap, neste caso, é o comando que está sendo executado no momento do trap.
Excluindo esse caso de canto de trap, se eu entendi corretamente, isso significa que, quando eu executo um comando, a variável BASH_COMMAND
contém esse comando. Não está absolutamente claro se essa variável não está definida após a execução do comando (isto é, é apenas avaialble enquanto o comando está em execução, mas não depois), embora se possa argumentar que ele é "o comando atualmente sendo executado ou prestes a ser executado ", não é o comando que foi executado .
Mas vamos verificar:
$ set | grep BASH_COMMAND=
$
Vazio. Eu teria esperado ver BASH_COMMAND='set | grep BASH_COMMAND='
ou talvez apenas BASH_COMMAND='set'
, mas vazio me surpreendeu.
Vamos tentar outra coisa:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
Bem, isso faz sentido. Eu executo o comando echo $BASH_COMMAND
e assim a variável BASH_COMMAND
contém a string echo $BASH_COMMAND
. Por que isso funcionou desta vez, mas não antes?
Vamos fazer a coisa set
novamente:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Então espere. Foi definido quando executei o comando echo
e não foi cancelado depois. Mas quando eu executei set
novamente, BASH_COMMAND
não foi definido para o comando set
. Não importa quantas vezes eu execute o comando set
aqui, o resultado permanece o mesmo. Então, a variável é definida ao executar echo
, mas não ao executar set
? Vamos ver.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
O que? Então a variável foi definida quando executei echo $BASH_COMMAND
, mas não quando executei echo Hello AskUbuntu
? Onde está a diferença agora? A variável é definida apenas quando o próprio comando atual força o shell a avaliar a variável? Vamos tentar algo diferente. Talvez algum comando externo desta vez, não um estrondo, por uma mudança.
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
Hmm, ok ... novamente, a variável foi definida. Então, meu palpite atual está correto? A variável é definida apenas quando precisa ser avaliada? Por quê? Por quê? Por motivos de desempenho? Vamos fazer mais uma tentativa. Vamos tentar grep para $BASH_COMMAND
em um arquivo, e como $BASH_COMMAND
deve conter um comando grep
, grep
deve grep para o comando grep
(ou seja, para ele mesmo). então vamos fazer um arquivo apropriado:
$ 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. O comando grep $BASH_COMMAND tmp
foi expandido para grep grep $BASH_COMMAND tmp tmp
(a variável é expandida apenas uma vez, é claro) e, por isso, usei grep
, uma vez em um arquivo $BASH_COMMAND
que não existe e duas vezes no arquivo tmp
.
Q1: Meu pressuposto atual é o seguinte:
-
BASH_COMMAND
é definido apenas quando um comando tenta realmente avaliá-lo; e
- não é não cancelado após a execução de um comando, mesmo que a descrição nos leve a acreditar nisso?
Q2: Se sim, por quê? Atuação? Se não, de que outra forma o comportamento na sequência de comandos acima pode ser explicado?
Q3: Por fim, existe algum cenário em que essa variável possa realmente ser usada de forma significativa? Eu estava realmente tentando usá-lo dentro de $PROMPT_COMMAND
para analisar o comando que está sendo executado (e fazer algumas coisas dependendo disso), mas eu não posso, porque assim que, dentro do meu $PROMPT_COMMAND
, eu executo um comando para procurar na variável $BASH_COMMAND
, a variável obtém conjuntos para esse comando. Mesmo quando eu faço MYVARIABLE=$BASH_COMMAND
no início do meu $PROMPT_COMMAND
, então MYVARIABLE
contém a string MYVARIABLE=$BASH_COMMAND
, porque uma atribuição é um comando também. (Esta questão não é sobre como eu poderia obter o comando atual dentro de uma execução de $PROMPT_COMMAND
. Há outras maneiras, eu sei.)
É um pouco como o princípio da incerteza de Heisenberg. Apenas observando a variável, eu mudo.