it-swarm.dev

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

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

288
Richard Hoskins

Tipo CtrlR na linha de comando e comece a digitar o comando anterior. Quando um resultado aparecer, continue batendo CtrlR para ver outros jogos. Quando o comando desejado aparecer, basta pressionar Enter

Note que enquanto CtrlR é o padrão, se você quiser que o comando (reverse-search-history) seja vinculado a CtrlT você poderia configurar isso com o seguinte:

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

Há um host inteiro de outros comandos bindable readline que estão disponíveis para você também. Dê uma olhada na bash man page .

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:

 $ história 

Vai imprimir uma lista de comandos junto com um índice numérico, como:

 $ histórico 
 1 claro 
 2 ls -al 
 3 vim ~/algum arquivo.txt 
 4 história 
 $ 

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

 $! 1 

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

Você também pode especificar offsets negativos relativos ao usar o designador !, portanto, usando nossa lista de histórico acima, se quisermos executar vim novamente, poderíamos fazer:

 $! -2 

Que basicamente está dizendo 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 um atalho para !-1).

O designador ! não o limita a especificar numericamente qual comando executar. hayalci mostrou que você pode instruir bash para executar um comando com base no texto que começa com (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 construtor shopt:

 $ 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 seu arquivo de inicialização .bashrc para que seja definida sempre que você efetuar login.

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

421
Sean Bright

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

!text

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

Mas eu sugiro que você coloque isso no seu .bashrc para evitar a execução do comando errado.

shopt -s histverify

Isso instrui bash tal que, após qualquer histórico de ações (como !!:s/prev_text/after_text), ele coloca a linha resultante no prompt de comando. Depois, você pode revisar ou editar o comando e pressionar Enter depois.

36
hayalci

Você também pode fazer:

history | grep "stuff"

ele retornaria algo como

num stuff

então você pode digitar

!num
30
Mitch

Eu prefiro usar history-search-backward sobre reverse-search-history. O primeiro permite que você digite alguns caracteres do comando then pressione a tecla de busca, ao invés de apertar a tecla de busca primeiro, então digite 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'
14
Keith

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
12
CurtH

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 durante a alteração de um Word. Digamos que você digitou o nome do diretório ou deseja alterar o nome do arquivo:

$ echo meu nome é bob 
 meu nome é bob 
 $ ^ bob ^ jordan 
 eco meu nome é jordan 
 meu nome é 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.

12
Jordan

Como a navegação pelo histórico usando Ctrl-r é um problema da IMO, você pode querer considerar hh :

https://github.com/dvorka/hstr

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

enter image description here

5
Martin Dvorak

No comando bash Prompt, digite control-R e, em seguida, digite alguns caracteres do comando desejado 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 ir para o próximo comando correspondente.

3
John1024

Se você tem seu Shell configurado para usar ligações de chave vi (set -o vi ou tendo set editing-mode vi em $HOME/.inputrc), então você pesquisa com <Esc>/some-command<Return> e aperta n (next) ou Shift-n (previous) para percorrer o histórico da linha de comando.

3
Fernando Basso

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

$ history | grep keyword
2
Mureinik