De acordo com o manual do 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 uma interceptação; nesse caso, é o comando que está sendo executado no momento da interceptação.
Tirando essa caixa de canto de armadilha de lado, se entendi corretamente, isso significa que, quando executo um comando, a variável BASH_COMMAND
contém esse comando. Não está absolutamente claro se essa variável está desmarcada após a execução do comando (ou seja, só está disponível enquanto o comando está sendo executado, mas não após), embora se possa argumentar que, uma vez que é "o comando atualmente sendo executado ou prestes a ser executado" , não é o comando que acabou de ser executado.
Mas vamos verificar:
$ set | grep BASH_COMMAND=
$
Esvaziar. Eu esperava 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, portanto, a variável BASH_COMMAND
contém a string echo $BASH_COMMAND
. Por que funcionou desta vez, mas não antes?
Vamos fazer a set
coisa novamente:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Então espere. Ele foi definida quando eu executei que echo
comando, e ele não foi desactivado depois. Mas quando eu executei set
novamente, BASH_COMMAND
não estava definido para o set
comando. Não importa quantas vezes eu executo o set
comando 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 eu executei echo $BASH_COMMAND
, mas não quando eu executei echo Hello AskUbuntu
? Onde está a diferença agora? A variável é definida apenas quando o próprio comando atual realmente força o shell a avaliar a variável? Vamos tentar algo diferente. Talvez algum comando externo desta vez, não um bash embutido, para variar.
$ /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 é configurada apenas quando precisa ser avaliada? Por quê? Por quê? Por razões de desempenho? Vamos fazer mais uma tentativa. Vamos tentar grep for $BASH_COMMAND
em um arquivo e, como $BASH_COMMAND
deve conter um grep
comando, grep
grep para esse grep
comando (ou seja, por si só). então vamos criar 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 então eu esperei grep
, uma vez em um arquivo $BASH_COMMAND
que não existe e duas vezes no arquivo tmp
.
Q1: Minha suposição atual está correta de que:
BASH_COMMAND
é definido apenas quando um comando tenta realmente avaliá-lo; e- é não unset após a execução de um comando, mesmo que a descrição pode levar-nos a acreditar que sim?
P2: 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 significativamente? Na verdade, eu estava tentando usá-lo $PROMPT_COMMAND
para analisar o comando que está sendo executado (e fazer algumas coisas dependendo disso), mas não posso, porque assim que, dentro do meu $PROMPT_COMMAND
, eu executo um comando para examinar a variável $BASH_COMMAND
, a variável obtém conjuntos para esse comando. Mesmo quando eu faço MYVARIABLE=$BASH_COMMAND
logo no início do meu $PROMPT_COMMAND
, então MYVARIABLE
contém a string MYVARIABLE=$BASH_COMMAND
, porque uma atribuição também é um comando. (Esta questão não é sobre como eu poderia obter o comando atual dentro de uma $PROMPT_COMMAND
execução. Existem outras maneiras, eu sei.)
É um pouco como no princípio da incerteza de Heisenberg. Apenas observando a variável, eu a altero.
bash
über-gurus reais lá.