Estou tentando criar um script bash que salvará o histórico do terminal em um arquivo chamado hist.txt. O uso history > hist.txt
não parece funcionar no script bash, mas funciona bem quando executado na linha de comando.
Qualquer orientação é muito apreciada.
Obrigado Judy
~/.bash_history
arquivo do usuário .Respostas:
Resposta curta
Execute o script com
source
ou.
:ou
Este último é um pouco mais compatível entre diferentes conchas.
Resposta longa
Esta pergunta destaca um ponto importante, que é que os scripts de shell são executados em seu próprio contexto. Para ver o que isso significa, considere o seguinte script de shell:
Se você executar isso, obterá uma saída semelhante a esta:
Mas você notará que, depois de executar o script, você ainda está no diretório em que estava antes de executá-lo: o
cd /
interior do script não afetou sua sessão - apenas afetou o contexto em que o script estava sendo executado, o que é criado para a execução do script e destruído quando ele retorna.O
source
comando 'lerá e executará comandos do argumento do nome do arquivo no contexto atual do shell'; portanto, qualquer comando comocd
esse dentro afetará sua sessão atual. Se você executasse o script acima, passando-o parasource
você, descobriria que acabaria dentro do diretório raiz após a execução .Nesse caso, o problema é que o
history
comando fornece o histórico do contexto atual do shell; o contexto do shell em que seu script é executado sem o usosource
não tem histórico; portanto, ele não grava nada no arquivo de saída. Se você o usar,source
ele será executado no contexto correto e funcionará conforme o esperado.NB:
source
é built-in, não um programa de uma concha per se - em Bash,source
é sinônimo de.
, mas em algumas conchas única.
vai funcionar - Eu useisource
nesta resposta porque é mais fácil de ler do que.
, mas para o máximo de compatibilidade,.
deve ser usado.fonte
Antes de tudo, observe que seu histórico já está em um arquivo. Se você estiver executando o bash, seu nome geralmente é
~/.bash_history
. Mais especificamente, é como você definiu a variávelHISTFILE
. Se você deseja copiá-lo para outro arquivo, basta executarcat "$HISTFILE" > hist.txt
Agora, por que o
history
comando não funciona em um script shell bash, é porque os scripts são executados em um shell filho não interativo da sua sessão atual do shell. Os shells filhos não herdam todo o ambiente do pai (portanto, nem todas as variáveis definidas), apenas as variáveis que foram exportadas. Para ilustrar, o script abaixo fará eco do valor da variável$var
:Agora, defina
$var
algo e execute o script:Em seguida, exporte a variável primeiro:
Como você pode ver, quando a variável foi exportada, ela está disponível para shells filhos.
Como mencionei antes, o histórico é armazenado no arquivo apontado pela variável
$HISTFILENAME
. Como isso não é exportado por padrão, ele não é definido ao executar um script:Como você pode ver no exemplo acima, a variável
HISTFILE
é definida na minha sessão normal do shell, mas fica vazia ao executar o script.Portanto, para obter o histórico, você tem algumas opções:
O
HISTFILE
valor padrão é$HOME/.bash_history
. Se você não mudou isso, basta executar este comando no seu script:Você pode passar a
$HISTFILE
variável para o seu script ecat
que:Salve o acima
foo.sh
e execute assim:Verifique se a variável é exportada. Adicione esta linha aos seus arquivos
~/.bash_profile
(se existir) ou~/.profile
(se~/.bash_profile
não existir):Em seguida, efetue logout e logon novamente e você poderá executar a
history > hist.txt
partir de um script conforme o esperado. Isso ocorre porqueexport VAR
significa "disponibilizar o $ VAR para conchas filho". Em termos práticos, isso significa que o valor deHISTFILE
será herdado pelo shell não interativo que você usa para executar seu script.Agora, enquanto o
HISTFILE
será definido, ele não foi lido pelo shell executando o script. Portanto, para que funcione, você precisahistory -r
primeiro ler . O script inteiro ficaria assim:Como alternativa, basta exportá-lo manualmente antes de executar o script:
Mas você ainda precisará
history -r
no script.Você pode
source
sugerir a resposta de @ p0llard .fonte