Remova uma determinada linha do arquivo de histórico do Bash


Respostas:


108

Você precisa fazer logoff e logon novamente ou executar history -apara que o histórico atual seja confirmado no disco.

Em seguida, basta editar o arquivo ~/.bash_history.


19
Se a variável de ambiente HISTFILE estiver configurada, o arquivo de histórico não será ~ / .bash_history, mas sim $ {HISTFILE}.
31513 Karolos

20
As entradas são gravadas no arquivo de histórico quando você sai do shell. Portanto, depois de inserir um comando que você deseja remover, é necessário fazer logoff e logon novamente ou usar 'history -d xxxx' para removê-los da sessão atual do shell.
harmic

3
mas como você excluiria o registro de edição do arquivo de histórico?
chiliNUT

5
@chiliNUT: Basta iniciar seu comando (por exemplo vim ~/.bash_history) com um espaço; Os comandos que começam com um espaço geralmente não são registrados (consulte $HISTCONTROL).
Cyrus

Eu não acho que isso é o caso na minha distribuição, mas em geral que faz sentido
chiliNUT

149

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

  1. A digitação history -d <line_number>exclui uma linha especificada do histórico na memória.
  2. A digitação history -wgrava o histórico atual da memória no ~/.bash_historyarquivo.

As duas etapas juntas removem a linha permanentemente do histórico da memória e também do arquivo .bash_history .


7
como excluir o último history -wdo histórico?
precisa saber é o seguinte

@KrIsHnA edit ~ / .bash_history manualmente
Alexander Myshov

5
Ou adicionar um espaço antes para impedir que ele seja adicionado, como em resposta de @ tao
Mark

Para encontrar <line_number>apenas history | grep [unwanted_content]para obter uma lista com todas as linhas que contêm [unwanted_content](como senhas).
AvL

Como você exclui várias linhas (específicas) (por ID)?
21418 Pathros

39

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

$ export HISTCONTROL=ignorespace

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

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

32

Primeiro de tudo, se o comando que você está prestes a emitir for sensível, inseguro ou se você não precisar dele, bagunçando seu histórico, é melhor / mais rápido impedir que ele entre no histórico. Certifique-se de que $HISTCONTROLcontém ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Em seguida, prossiga com qualquer espaço que você não desejar em seu histórico:

(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 do bash ainda esteja aberta, o comando ainda não tocou o disco. Para excluir o comando anterior no histórico, emita:

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

Observe o espaço à esquerda; Este comando requer ignorespace, caso contrário, ele será excluído!

Se você deseja excluir os últimos comandos, localize 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

Nesse caso, 602 e 599. Emita:

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

(Sem ignorespace, seria 603..599.)

Se você não deseja que nenhum histórico da sua sessão atual atinja o disco, saia usando:

(bash)$ kill -9 $$

A abordagem até agora é nem mesmo permitir que itens sensíveis do histórico sejam gravados no disco para segurança extra, porque, em teoria, os dados excluídos da mídia não volátil ainda podem ser recuperados.

Se, no entanto, os comandos que você deseja remover forem de uma sessão anterior, eles já terão sido anexados à $HISTFILEsaída. Manipulando a história com os comandos acima ainda só vai acrescentar os restantes novos itens para o $HISTFILE, na saída . Para sobrescrever a $HISTFILEexibição da sessão atual de todo o histórico, instale agora :

(bash)$  history -w

Obviamente, para itens do histórico que já estão no disco, a alternativa para editar o histórico com history -dcomandos e depois emitir history -wé editá-lo $HISTFILEcom um editor de texto.


1
“Manipulando a história com os comandos acima ainda só acrescentar os restantes novos itens para o $HISTFILE, na saída .” Na verdade, isso não é exatamente verdade. Parece apenas acrescentar os novos itens restantes que se destacam do tamanho do histórico original. Por exemplo, se eu remover 5 itens originais e adicionar 15 novos, apenas os 10 últimos serão anexados, enquanto eu esperaria que todos os 15 novos fossem anexados. Eu acho que isso é um bug, porque não consigo ver como isso é uma funcionalidade desejável.
James Haigh

1
Eu acho que o bash toma nota do comprimento original. No encerramento da sessão, presume-se que ele acrescenta itens cujo número é maior que esse valor. Se esse valor for diminuído toda vez que um item for excluído, com um número menor ou igual a esse valor, ele funcionará conforme o esperado. ;-)
James Haigh

15

Várias técnicas:

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

Se você digitou alguma senha em uma linha de comando, percebe que todos os comandos estão registrados, você pode:

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

     kill -9 $$

    Isso eliminará todo o histórico atual.

  2. Digite ↑ (up arrow)na sessão do bash aberto até que as informações sigilosas sejam exibidas, use as teclas de edição de linha como Ctrl+ Wpara excluir as informações sigilosas e , ↓ (down arrow) até que uma nova linha vazia seja solicitada, antes de digitar Enter.

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 todo o seu histórico:

Um sedcomando simples pode fazer o trabalho:

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

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

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

Isso será executado head -n1com a entrada do terminal. Parece que o seu terminal está travado (não haverá um prompt); basta digitar as informações que você deseja excluir do arquivo. Esse é um truque para permitir que você insira (parte de) um comando sem realmente digitá-lo na linha de comando, tornando-o inelegível para inclusão no registro do histórico. Em seguida sed, usará o texto digitado para pesquisar .bash_history e excluir todas as linhas que contêm as informações confidenciais. Nota: se o seu padrão de informações confidenciais contiver barras, você deve escapá-las com barras invertidas ou alterar o sedcomando 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 poderia ser 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 de 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

Por fim, para garantir que isso não fique em outro arquivo esquecido:

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

listará todos os arquivos em questão.

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 enraizada em .. Nota: mesmo que este comando use xargs -0, ele não manipulará arquivos com novas linhas em seus nomes.


11

Localize a linha que deseja excluir pressionando ↑ (up arrow)até que apareça e, em seguida, pressione Ctrl+ U. Isso deve remover a linha.

Se você usar o historycomando, poderá ver que a linha foi substituída por um asterisco.


2
Na verdade, acredito que você deve mover o cursor até a linha, pressione Ctrl + U e , em seguida, mova o cursor para cima ou para baixo para outra linha (possivelmente a em branco na parte inferior da lista). Além disso, estritamente falando, a linha não foi substituída por um asterisco. Em vez disso, o comando foi apagado e o número do histórico foi anexado com a *.
G-Man

1
Isso se torna muito mais poderoso com Ctrl + R (pesquisa reversa no histórico incremental) e, por exemplo, [Fim], Ctrl + U
veja

4

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

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

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

history -d $((HISTCMD-2))

2
Este parecia que funcionou, mas history | grep <string>ainda mostra todas as linhas que pretendiam excluir ...
Brock Hensley

1
Isso excluirá as linhas do histórico incorretas após a exclusão do primeiro !!
mivk

1
Mas, felizmente, ele apenas imprime os comandos de exclusão incorretos. O seguinte imprimiria os comandos de exclusão corretos:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk

3

Se você precisar remover um intervalo de linhas do histórico, a seguinte função do bash poderá 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 normalmente adicionada a $HOME/.bashrc. Para usar a função imediatamente, você precisará que o arquivo seja lido novamente pelo shell em execução ( . $HOME/.bashrc). Em seguida, para excluir, por exemplo, os comandos 200-210 do histórico:

$ histdel 200 210

(Nota: esta pergunta está entre os principais resultados da pesquisa, se você excluir um intervalo de comandos do histórico do bash. Portanto, embora o acima seja mais do que o que a pergunta faz, pode ser útil para alguns leitores.)


3
Formas alternativas para a fordeclaração: for n in $(seq "$2" "$1")é estilisticamente preferida por alguns e, se seqnão funcionar, tente for ((n="$2"; n>="$1"; n--)).
Scott

3
history | sed -i 59d

59 é o número da linha. Não pode ser nada mais doce do que isso :)


3

Apenas tente estes,

$ history

isso exibirá o ID do histórico e o comando, por exemplo

.
.
211 ls
212 javac Welcome.java
213 java bem-vindo
.
.

usar,

$ history -d 211

Aqui 211 é o id da história. Agora verifique isso usando

$ history

.
.
211 javac Welcome.java
212 java bem-vindo
.
.


2

Sei que já faz muito tempo que essa pergunta foi feita e respondida, mas mostrarei meu método para limpar meu arquivo de histórico e fazer logout ao mesmo tempo.

Eu corro : history -w && nano "${HISTFILE}" && history -c && exit

O que ele faz é simples:

  1. history -w : escreve o histórico em cache dentro "${HISTFILE}"
  2. nano "${HISTFILE}": permita-me editar "${HISTFILE}"Você pode usar um script sed ou o que quiser limpar seu"${HISTFILE}"
  3. history -c : limpe o histórico em cache para que este último comando não seja anexado.
  4. exit : desconecte-me anexando o histórico em cache ... mas está vazio;)

Após esse comando, você será desconectado com um arquivo de histórico limpo. Faça o login para verificar seu histórico;)

Espero que isso ajude alguém.


1

Você também pode editar o arquivo de histórico diretamente, por exemplo, nano .bash_historyse estiver no shell bash?

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.