
No terminal bash, se eu executar o seguinte loop for:
for i in {1..5}; do echo $i; done
Os echo
comandos não são adicionados ao histórico do shell atual. É porque os comandos for (na do
seção) são executados em subshell? Em caso afirmativo, existe uma maneira de executá-los no shell atual? Ou não é possível porque está "funcionando" for
na hora?
Editar: Dado que todo o loop for é considerado um único comando composto, se eu remover o loop for e escrever os comandos individuais em cinco linhas, todos os cinco não deverão ser adicionados ao histórico?
Eu fiz o seguinte:
#!/bin/bash
set -o history
var=5
echo $((var--))
echo $((var--))
echo $((var--))
echo $((var--))
echo $((var--))
e executei o script usando source
. Ainda na história mostra apenas uma declaração de eco echo $((var--))
e não todas as cinco. Por outro lado, se em vez de cinco echo $((var--))
eu colocar cinco comandos echo 5
, echo 4
, ... echo 1
todos os cinco serão adicionados ao histórico.
Por que?
Responder1
Seu script não salvaria o histórico em ~/.bash_history em primeiro lugar, a menos que você exportasse $HISTFILE
antes de executá-lo. Como diz man bash
isso é porque:
Se HISTFILE não estiver definido ou se o arquivo de histórico não for gravável, o histórico não será salvo.
HISTFILE
não é uma variável de ambiente, é uma variável de shell e, portanto, não está disponível em scripts que são processos filhos. E mesmo se você executasse esses comandos
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
(observe os espaços em branco após o prompt) em uma sessão interativa e não em um script, eles não seriam salvos em ~/.bash_history na prática, nem porque distribuições populares do Linux, como o Ubuntu, definidas
HISTCONTROL
como ignorespace
ou ignoreboth
(que é um alias para
ignorespace
e ignoredups
) para não salve comandos que começam com um ou mais espaços em branco. Isto é especialmente útil se você trabalha em um servidor compartilhado com outros usuários e intencionalmente não deseja salvar um determinado comando no histórico para que outras pessoas possam vê-lo, por exemplo, porque contém sua senha ou outras informações confidenciais.
Mas mesmo que não houvesse espaços em branco antes do comando:
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
você provavelmente acabaria com apenas uma única echo $((var--))
entrada em ~/.bash_history porque HISTCONTROL
normalmente contém
ignoredups
ou o arquivo ignoreboth
. Tudo isso está descrito na HISTCONTROL
seção da página de manual do Bash que você pode invocar em man bash
seu sistema.