Remover uma determinada linha do ficheiro de histórico Bash
Como posso remover uma determinada linha da base de dados history
?
Como posso remover uma determinada linha da base de dados history
?
Pode conseguir a remoção do ficheiro do histórico usando a linha de comando em duas etapas:
history -d <line_number>
apaga uma linha específica do histórico em memória. history -w
escreve o histórico actual em memória para o ficheiro ~/.bash_history
. Os dois passos juntos retiram a linha permanentemente da história em memória history e do ficheiro .bash_history também.
Para prevenir que um comando seja adicionado ao histórico em primeiro lugar, certifique-se de que a variável de ambiente HISTCONTROL
contém entre os seus valores separados por dois pontos o valor ignorespace
, por exemplo (adicionar por exemplo a .bashrc
):
$ export HISTCONTROL=ignorespace
Isto evitará que qualquer comando com um espaço principal seja adicionado ao histórico. Poderá então limpar completamente o histórico executando
$ history -c -w
^-- additional space character
Em primeiro lugar, se o comando que está prestes a emitir for sensível, inseguro, ou se simplesmente não precisar dele a desorganizar a sua história, é melhor/mais rápido apenas impedi-lo de entrar na história em primeiro lugar. Certifique-se de que $HISTCONTROL
contém ignorespace
:
(bash)$ echo $HISTCONTROL
ignoredups:ignorespace
Então prossiga com qualquer comando que não queira na sua história com um espaço:
(bash)$ sensitive-cmd-with --password 82cf7dfe
(bash)$ rm -r... # One-off recursive remove; mustn't be accidentally repeated!
Se colocar acidentalmente um comando indesejado na história, desde que a sua sessão de bash ainda esteja aberta, o comando ainda não tocou no disco. Para apagar o comando anterior no historial, emitir:
(bash)$ history -d $((HISTCMD-1))
Note o espaço principal; este comando requer ignorespace
, caso contrário, apagar-se-á a si mesmo!
Se quiser apagar os últimos comandos, encontre o último e primeiro número do historial:
(bash)$ history 5
598 ok
599 sensitive
600 unsafe
601 doesn
Neste caso 602 e 599. Depois número:
(bash)$ for i in {602..599}; do history -d $i; done “`
(Sem ignorespace
, seria 603..599.)
Se não quiser qualquer histórico da sua sessão actual para bater no disco, saia usando:
(bash)$ kill -9 $$
A abordagem até agora é nem sequer deixar que itens sensíveis do histórico sejam escritos no disco para segurança extra, porque em teoria os dados apagados de meios não voláteis ainda podem ser recuperados.
Se, no entanto, o(s) comando(s) que deseja remover forem de uma sessão anterior, já terão sido anexados ao $HISTFILE
à saída. Manipulando o histórico com os comandos acima referidos, apenas apenderá os restantes _novos itens ao $HISTFILE
, na saída. Para sobreescrever o $HISTFILE
com a visão da sessão actual do histórico de entire, em curso, edição:
(bash)$ history -w
Claro que para os itens do histórico já em disco, a alternativa à edição do histórico com os comandos history -d
, emitindo em seguida o history -w
, é editar o $HISTFILE
com um editor de texto.t-work
602 otherwise-unwanted
”`
Neste caso 602 e 599. Depois número:
0x1&
(Sem 0x6&, seria 603..599.)
Se não quiser qualquer histórico da sua sessão actual para bater no disco, saia usando:
0x1&
A abordagem até agora é nem sequer deixar que itens sensíveis do histórico sejam escritos no disco para segurança extra, porque em teoria os dados apagados de meios não voláteis ainda podem ser recuperados.
Se, no entanto, o(s) comando(s) que deseja remover forem de uma sessão anterior, já terão sido anexados ao 0x6& à saída. Manipulando o histórico com os comandos acima referidos, apenas apenderá os restantes _novos itens ao 0x6&, na saída. Para sobreescrever o 0x6& com a visão da sessão actual do histórico de entire, em curso, edição:
0x1&
Claro que para os itens do histórico já em disco, a alternativa à edição do histórico com os comandos 0x6&, emitindo em seguida o 0x6&, é editar o 0x6& com um editor de texto.
Várias técnicas:
Se tiver introduzido alguma palavra-passe numa linha de comando, então perceba que todos os comandos estão registados, poderá ou não estar registado:
forçar a saída da sessão actual sem guardar o histórico:
Digitar ↑ (seta para cima) na sessão de bash aberta até que a informação sensível seja mostrada, depois usar teclas de edição de linha como Ctrl+W para apagar a informação sensível, e então* ↓ (seta para baixo) até que uma nova linha vazia seja solicitada, antes de digitar Enter.
Se perceber que a informação sensível já está armazenada, e quiser apagá-la, mas não todo o seu histórico:
Um simples comando sed
poderia fazer o trabalho:
sed -e '/SeNsItIvE InFo/d' -i .bash_history
mas, ao digitar isto, cria outra linha do histórico contendo o padrão de pesquisa (informação sensível) que está a tentar apagar. Por isso, poderia:
sed -e "/$(head -n1)/d" -i .bash_history
Isto funcionará head -n1
com a entrada do terminal. Aparecerá que o seu terminal está pendurado (não haverá uma solicitação); basta digitar a informação que deseja apagar do ficheiro. Este é um truque para lhe permitir introduzir (parte de) um comando sem o escrever na linha de comando, tornando-o assim inelegível para inclusão no registo histórico. Depois sed
utilizará o texto que digitou para pesquisar .bash_history
e apagar todas as linhas que contenham a informação sensível. Nota: se o seu padrão de informação sensível contém barra(s), deve escapar-lhes com barras invertidas, ou então alterar o comando sed
para usar esta sintaxe para especificar um delimitador que não aparece no padrão:
sed -e "\|$(head -n1)|d" -i .bash_history
Outra forma poderia ser apagar apenas a informação sensível, mas manter os comandos que contêm a informação. Para isso, poderia simplesmente substituir a informação sensível por texto substituto à sua escolha:
sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.
Finalmente, para ter a certeza de que esta não ficará em outro ficheiro esquecido:
SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"
listará todos os ficheiros em causa.
find . -type f -print0 |
xargs -0 grep -l "$SENSITIVEINFO" |
tr \n \0 |
xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i
substituirá todas as ocorrências de informações sensíveis em todos os ficheiros da árvore de directórios enraizados em .
. Nota: ainda que este comando utilize xargs -0
, não irá tratar ficheiros com novas linhas nos seus nomes.
Localize a linha que pretende apagar premindo ↑ (seta para cima) até aparecer, depois prima Ctrl+U. Isso deverá remover a linha.
Se utilizar o comando history
, pode ver que a linha foi substituída por um asterisco.
Se precisar de remover uma série de linhas da história, a seguinte função bash pode poupar-lhe algum tempo:
function histdel() {
[$# -eq 1] && history -d "$1" && history -w
if [$# -eq 2 -a "$1" -le "$2"]; then
for n in `seq "$2" "$1"`; do
history -d "$n"
done
history -w
fi
}
Função deve ser tipicamente adicionada a $HOME/.bashrc
. Para utilizar a função de imediato, terá de ter o ficheiro lido novamente pela sua shell em execução (. $HOME/.bashrc
). Depois, para apagar, por exemplo, comandos 200-210 do histórico:
$ histdel 200 210
(Nota: Esta pergunta está entre os resultados de pesquisa mais procurados se procurar apagar uma série de comandos do histórico da bash. Assim, embora a pergunta acima seja mais do que aquilo que a pergunta faz, pode ser útil para alguns leitores).
Basta experimentar estes,
$ history
isto mostrará a id da história e o comando, por exemplo
. . . 211 ls 212 javac Welcome.java 213 java welcome . .
.
$ history -d 211
Aqui 211 é a id da história. Agora verifique isto usando
$ history
. . . 211 javac Welcome.java 212 java welcome . . .
Sei que já passou muito tempo desde que esta pergunta foi feita e respondida, mas vou mostrar-vos o meu método para limpar o meu ficheiro de história e sair ao mesmo tempo.
Eu corro :history -w && nano "${HISTFILE}" && history -c && exit
O que faz é simples:
history -w
: escreve a história em cache dentro de "${HISTFILE}"
nano "${HISTFILE}"
: permite-me editar "${HISTFILE}"
Podes usar um sed script ou o que quiseres para limpar o teu "${HISTFILE}"
history -c
: limpar o histórico em cache para que este último comando não seja anexado. exit
: log me out anexando o historial em cache… mas está vazio ;) Após esse comando, será desconectado com um ficheiro de histórico limpo. Entre para verificar o seu histórico ;)
Espero que isto ajude alguém.