Como posso pesquisar o histórico bash e reexecutar um comando?

277

Posso pesquisar o histórico no bash e executar o resultado?

    
por Richard Hoskins 17.07.2009 / 21:23

10 respostas

399

Digite Ctrl R na linha de comando e comece a digitar o comando anterior. Uma vez que um resultado apareça, continue pressionando Ctrl R para ver outras combinações. Quando o comando desejado aparecer, simplesmente pressione Enter

Note que enquanto Ctrl R é o padrão, se você quiser que o comando ( reverse-search-history ) seja ligado a Ctrl T você poderia configurar isso com o seguinte:

bind '"\C-t": reverse-search-history'

Há toda uma série de outros comandos bindable readline que estão disponíveis para você também. Dê uma olhada na página bash man .

O Bash tem muitos recursos para pesquisar e acessar o histórico de comandos interativos. O mais básico deles é o history builtin. Digitando apenas:

$ history

Imprimirá uma lista de comandos junto com um índice numérico, como:

$ history
1 clear
2 ls -al
3 vim ~/somefile.txt
4 history
$

Você pode executar qualquer um desses comandos usando seu índice numérico, precedendo o índice com um único ! , como Mitch apontou:

$ !1

Será executado o comando clear . O histórico embutido tem muitos recursos em si, você pode ver mais nas páginas bash e history man.

Você também pode especificar compensações negativas relativas ao usar o ! designador, portanto, usando nossa lista de histórico acima, se quisermos executar vim novamente, poderíamos fazer:

$ !-2

Que basicamente diz bash para executar o comando que você executou "dois comandos atrás". Para executar o comando anterior na lista do histórico, podemos usar apenas !! (que é apenas uma abreviação de !-1 ).

O designador ! não limita você a especificar numericamente qual comando deve ser executado. hayalci mostrou que você pode instruir bash a executar um comando com base no texto com o qual começa (usando ! ) ou texto dentro do próprio comando (usando !? ). Novamente, usando nossa lista de histórico de exemplo acima, se quisermos executar clear novamente, tudo o que precisamos fazer é digitar:

$ !cl

e pressione Enter . E quanto a vim ? Isso é tão simples quanto:

$ !?some

O ponto mais importante da resposta de hayalci é a chamada para o shopt builtin:

$ shopt -s histverify

Isso habilitará a verificação de histórico para que os comandos correspondidos pelos designadores ! , !! e !? não sejam executados cegamente, mas preenchidos na linha de comando para que você possa garantir que eles não farão mal antes de executá-los. Isso é ainda mais importante quando você está executando comandos como o usuário root. Essa opção pode ser configurada no arquivo de inicialização .bashrc , para que seja definida sempre que você efetuar login.

Como já foi apontado, todas essas informações podem ser coletadas da página bash man . Para o!, !! e! designadores, dê uma olhada na Seção 9.3 Expansão do Histórico .

    
por 17.07.2009 / 21:25
35

Como alternativa ao crtl + R , você pode pesquisar o histórico digitando

!text

Isto irá procurar o histórico pelo comando mais recente começando com 'text'.

Mas sugiro que você coloque isso em seu .bashrc para evitar a execução de comandos errados.

shopt -s histverify

Isso instrui o bash de forma que, após qualquer ação do histórico (como !!:s/prev_text/after_text ), coloque a linha resultante no prompt de comando. Então você pode rever ou editar o comando e pressionar Enter depois.

    
por 17.07.2009 / 22:40
28

Você também pode fazer:

history | grep "stuff"

retornaria algo como

num stuff

então você pode digitar

!num
    
por 17.07.2009 / 22:21
14

Eu prefiro usar history-search-backward sobre reverse-search-history. O primeiro permite que você digite alguns caracteres do comando então pressione a tecla de busca, ao invés de apertar a tecla de busca primeiro e depois digitar a string de busca.

Por padrão no meu sistema, M-p e M-n se ligam a funções similares, mas eu prefiro vincular as teclas de seta:

bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
    
por 02.02.2011 / 21:32
12

Excelente writeup, Sean! Eu colocaria isso em um comentário, mas tenho alguns pontos de reputação tímidos. : -)

Outra técnica relacionada e útil é a capacidade de executar um comando anterior ao alterar uma palavra. Digamos que você digitou o nome do diretório ou deseja alterar o nome do arquivo:

$ echo my name is bob
my name is bob
$ ^bob^jordan
echo my name is jordan
my name is jordan

Observe que o comando é expandido, substituído e enviado antes que o comando seja executado, portanto, se o comando errado for executado, você poderá ver o que o bash achou que estava fazendo.

    
por 10.09.2009 / 16:23
12

Eu tenho um ótimo apelido, h. É realmente apenas "history | grep", mas eu filtro entradas anteriores de "comando h" com o "grep -E -v"

alias h="history | grep -E -v '^ *[0-9]+ *h ' | grep "

usado como

h aliases
2003  less .bash_aliases
    
por 25.09.2014 / 18:45
5

Como a navegação pelo histórico usando Ctrl-r é um problema da IMO, talvez seja necessário considerar hh :

link

que torna a navegação muito mais simples, direta e eficiente - incluindo a execução do comando:

    
por 18.12.2014 / 17:37
3

No prompt de comando do bash, digite control-R e digite alguns caracteres do comando que você deseja e o recurso de linha de leitura de bash pesquisará o histórico de comandos desse comando.

Depois de iniciar a pesquisa, você pode digitar control-R novamente para pular para o próximo comando correspondente.

    
por 04.09.2014 / 06:55
3

Se o seu shell estiver configurado para usar vi ( set -o vi ou com set editing-mode vi em $HOME/.inputrc ), pesquise com <Esc>/some-command<Return> e clique em n (próximo) ou Shift-n (anterior) para percorrer o histórico da linha de comando.

    
por 22.11.2015 / 16:21
2

CTRL + R funciona muito bem, como o @ John1024 sugeriu, mas é um pouco entediante se muitos de seus comandos recentes forem semelhantes e você quiser uma maneira rápida de varrê-los todos. Uma alternativa seria usar history :

$ history | grep keyword
    
por 04.09.2014 / 07:11

Tags