eu executei
history > before; (history -d $n); history > after
onde $n
é o número correspondente ao último comando que digitei na mesma sessão interativa antes de executar esta linha,
O resultado é que a linha marcada $n
não é removida do histórico. Se eu remover os parênteses para que history -d
seja executado no shell atual, ele funcionará conforme documentado.
Como entender esse comportamento? É verdade que todos os scripts que manipulam a história precisam ser source
d?
Cada processo de shell tem sua própria ideia do que é o histórico da linha de comando. Quando um shell interativo sai, ele gravará seu histórico lembrado
~/.bash_history
para o próximo shell pegar, mas essa é a extensão da cooperação entre os processos do shell.Em seu comando, o
()
faz o fork do shell uma cópia de si mesmo para executar ohistory -d
comando. O processo filho começa com uma cópia do estado interno do pai, então ele conhece o histórico e pode fazer alterações em sua cópia.No entanto, quando o subshell sai, sua cópia do histórico (que acabou de ser reescrita) é descartada junto com o restante de seu estado interno). O subshell sabe que é um subshell, então nem se preocupa em escrever
~/.bash_history
.Um script que não é originado geralmente não pode manipular o histórico, porque é interpretado por um novo shell não interativo que nem lê
~/.bash_history
na inicialização.Você pode fazer com que o shell se comporte como um shell interativo especificando-o na linha de comando:
O shell que executa esse script anexará seus comandos (que incluem a linha shebang e o
echo something
) ao~/.bash_history
que encontrar no disco. Mas é claro que isso não afeta a cópia do histórico na memória do processo shell do qual você invoca o script e, quando ele sair, as alterações feitas no script~/.bash_history
serão perdidas de qualquer maneira.