Questão Remover uma determinada linha do arquivo de histórico do Bash


Como posso remover uma determinada linha de historybanco de dados?


128


origem




Respostas:


Você precisa sair e voltar ou executar history -a então o histórico atual está comprometido com o disco.

Então apenas edite o arquivo ~/.bash_history.


95



Se a variável de ambiente HISTFILE estiver definida, o arquivo de histórico não é ~ / .bash_history, mas sim $ {HISTFILE}. - Karolos
As entradas são gravadas no arquivo de histórico quando você sai do shell. Portanto, depois de inserir um comando que você gostaria de remover, você precisa fazer logout e voltar, ou usar o 'histórico -d xxxx' para removê-los da sessão atual do shell. - harmic
mas como você excluiria o registro de edição do arquivo de histórico? - chiliNUT
@chiliNUT: Basta iniciar seu comando (por exemplo, vim ~/.bash_history) com um espaço; comandos que começam com um espaço geralmente não são registrados (veja $HISTCONTROL). - cYrus
Eu não acho que é o caso da minha distribuição, mas em geral isso faz sentido - chiliNUT


Você pode conseguir a remoção do arquivo de histórico usando a linha de comando em duas etapas:

  1. Digitando history -d <line_number> exclui uma linha especificada do histórico na memória.
  2. Digitando history -w escreve o histórico atual na memória para o ~/.bash_history Arquivo.

Os dois passos juntos removem a linha permanentemente da memória história e do .bash_history arquivo também.


140



como excluir o último history -w da história? - KrIsHnA
@KrIsHnA editar ~ / .bash_history manualmente - Alexander Myshov
Ou adicione um espaço antes para evitar que seja adicionado, como na resposta do @ tao - Mark
Encontrar <line_number> somente history | grep [unwanted_content] para obter uma lista com todas as linhas contendo [unwanted_content] (como senhas). - AvL
Como você exclui várias linhas (específicas) (por id)? - Pathros


Para evita um comando seja adicionado ao histórico em primeiro lugar, certifique-se de que a variável de ambiente HISTCONTROL contém entre seus valores separados por dois pontos o valor ignorespace, por exemplo (adicione, por exemplo, .bashrc):

$ export HISTCONTROL=ignorespace

Isso impedirá que qualquer comando com um espaço à esquerda seja adicionado ao histórico. Você pode então limpar o histórico completamente executando

$  history -c -w
  ^-- additional space character

37





Primeiro de tudo, se o comando que você está prestes a emitir é sensível, inseguro, ou você simplesmente não precisa que ele atravesse seu histórico, é melhor / mais rápido apenas impedir que ele entre no histórico. Certifique-se de que $HISTCONTROL contém ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Em seguida, continue com qualquer comando que você não queira em seu histórico com um espaço:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

Se você acidentalmente colocar um comando indesejado no histórico, desde que sua sessão bash ainda esteja aberta, o comando ainda não tocou no disco. Para excluir o comando anterior no histórico, emita:

(bash)$  history -d $((HISTCMD-1))

Observe o espaço principal; este comando requer ignorespace, caso contrário, apenas irá apagar-se!

Se você quiser excluir os últimos comandos, encontre o último e o primeiro número do histórico:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

Neste caso, 602 e 599. Em seguida, emita:

(bash)$  for i in {602..599}; do history -d $i; done

(Sem ignorespaceseria 603.599.)

Se você não quiser qualquer histórico da sua sessão atual para acertar o disco, saia usando:

(bash)$ kill -9 $$

A abordagem até agora é a de não deixar que itens de histórico sensíveis sejam gravados em disco para segurança extra, porque, em teoria, os dados excluídos de mídias não voláteis ainda podem ser recuperados.

Se, no entanto, o comando (s) que você deseja remover for de uma sessão anterior, eles já terão sido anexados à $HISTFILE na saída. Manipular a história com os comandos acima ainda será apenas acrescentar o restante Novo itens para o $HISTFILE, na saída. Para sobrescrever a $HISTFILE com a visão da sessão atual do inteira história, agora mesmo, questão:

(bash)$  history -w

Claro que para itens de histórico já em disco, a alternativa para editar o histórico com history -d comandos então emissão history -w, é editar o $HISTFILE com um editor de texto.


30



”Manipular a história com os comandos acima ainda será acrescentar o restante Novo itens para o $HISTFILE, na saídaNa verdade, isso não é exatamente verdade. Parece que apenas acrescenta itens novos remanescentes que "se destacam" da duração do histórico original. Por exemplo. Se eu remover 5 itens originais e adicionar 15 novos, apenas os 10 últimos novos serão adicionados, enquanto eu esperaria que todos os 15 novos fossem anexados. Eu acho que isso é um bug porque eu não consigo ver como isso é uma funcionalidade desejável. - James Haigh
Eu acho que o bash toma nota do comprimento original. No fechamento da sessão, presumivelmente, anexa itens cujo número é maior que esse valor. Se esse valor fosse diminuído toda vez que um item fosse excluído cujo número fosse menor ou igual a esse valor, ele funcionaria conforme o esperado. ;-) - James Haigh


Várias técnicas:

Impedir que informações confidenciais sejam armazenadas no arquivo de histórico

Se você inseriu alguma senha em uma linha de comando, então perceba que todos os comandos estão registrados, você poderia:

  1. Força a saída da sessão atual sem salvar o histórico:

     kill -9 $$
    

    Isso eliminará todo o histórico atual.

  2. Tipo Up (seta para cima) na sessão bash aberta até que as informações confidenciais sejam mostradas, use as teclas de edição de linha como Ctrl+W para excluir as informações confidenciais e então  ↓ (seta para baixo) até que uma nova linha vazia seja solicitada, antes digitando Entrar.

Excluir informações confidenciais do arquivo de histórico

Se você perceber que informações confidenciais já estão armazenadas e deseja excluí-las, mas não o histórico inteiro:

Um simples sed comando poderia fazer o trabalho:

sed -e '/SeNsItIvE InFo/d' -i .bash_history

mas, conforme você digita isso, você cria outra linha de histórico contendo o padrão de pesquisa (informações confidenciais) que você está tentando excluir. Então você poderia:

sed -e "/$(head -n1)/d" -i .bash_history

Isso vai rodar head -n1 com entrada do terminal. Aparecerá que seu terminal está travado (não haverá um prompt); basta digitar as informações que você deseja excluir do arquivo. Este é um truque para você entrar (parte de) um comando sem realmente digitá-lo na linha de comando, tornando-o inelegível para inclusão no registro histórico. Então sed usará o texto que você digitou para pesquisar .bash_history e apague todas as linhas contendo as informações sensíveis. Nota: se o seu padrão de informações confidenciais contiver barra (s), você deve escapar deles com barras invertidas, ou então mudar o sed comando para usar esta sintaxe para especificar um delimitador que não apareça no padrão:

sed -e "\|$(head -n1)|d" -i .bash_history

Outra maneira seria excluir apenas as informações confidenciais, mas manter os comandos que contêm as informações. Para isso, você pode simplesmente substituir informações confidenciais por um texto substituto à sua escolha:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

Excluir informações confidenciais de qualquer arquivo em uma árvore específica

Finalmente, para ter certeza de que isso não vai ficar em outro arquivo esquecido:

SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"

listará todos os arquivos relacionados.

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 confidenciais em todos os arquivos na árvore de diretórios com raiz em .. Nota: mesmo que este comando use xargs -0, ele não manipulará arquivos com novas linhas em seus nomes.


14





Localize a linha que deseja excluir pressionando Up (seta para cima) até que apareça e pressione Ctrl+você. Isso deve remover a linha.

Se você usar o history comando, você pode ver a linha foi substituída por um asterisco.


10



Na verdade, acredito que você deve cursar até a linha, pressione Ctrl + U, e, em seguida, o cursor para cima ou para baixo para outra linha (possivelmente o em branco no final da lista). Além disso, estritamente falando, a linha não foi substituída por um asterisco. Pelo contrário, o comando foi apagado e número histórico foi anexado com um *. - G-Man
Isso se torna muito mais poderoso com Ctrl + R (busca de histórico incremental reverso), então, e. [End], Ctrl + U - sehe


Se você precisar remover várias linhas ao mesmo tempo eu normalmente uso isso:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

Se você precisar remover o último comando, você pode usar:

history -d $((HISTCMD-2))

4



Isso parecia que funcionou, mas history | grep <string> ainda mostra todas as linhas que afirmou excluir ... - Brock Hensley
Isto irá apagar as linhas do histórico erradas depois de deletar a primeira! - mivk
Mas, felizmente, apenas imprime os comandos de exclusão incorretos. O seguinte seria imprimir os comandos de exclusão corretos: history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}' - mivk


Se você precisar remover um intervalo de linhas do histórico, a seguinte função bash pode economizar 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
}

A função deve ser tipicamente adicionada a $HOME/.bashrc. Para usar a função imediatamente, você precisará ter o arquivo lido novamente pelo seu shell em execução (. $HOME/.bashrc). Então, para excluir, e. comandos 200-210 da história:

$ histdel 200 210

(Nota: Esta questão está entre os principais resultados da pesquisa se você procurar por excluir um intervalo de comandos do bash history. Então, enquanto o acima é mais do que a pergunta, ele pode ser útil para alguns leitores.)


3



Formas alternativas para o for declaração: for n in $(seq "$2" "$1") é estilisticamente preferido por alguns, e, se seq não funciona, tente for ((n="$2"; n>="$1"; n--)). - Scott