Comment rechercher dans l'historique bash et réexécuter une commande?

297

Puis-je rechercher l'historique dans bash et exécuter le résultat?

Richard Hoskins
la source

Réponses:

428

Tapez Ctrl Rsur la ligne de commande et commencez à taper la commande précédente. Une fois qu'un résultat apparaît, continuez à frapper Ctrl Rpour voir d'autres matches. Lorsque la commande souhaitée apparaît, appuyez simplement surEnter

Notez que while Ctrl Rest la valeur par défaut. Si vous souhaitez que la commande ( reverse-search-history) soit liée, Ctrl Tvous pouvez configurer cela avec les éléments suivants:

bind '"\ Ct": recherche inversée historique'

Il existe toute une série d'autres commandes pouvant être lues par Readline qui sont également disponibles. Jetez un coup d’œil à la bashpage de manuel .

Bash dispose de nombreuses fonctionnalités pour rechercher et accéder à l'historique des commandes interactives. Le plus fondamental est le historyconstruit. Taper juste:

$ histoire

Imprimera une liste de commandes avec un index numérique, tel que:

$ histoire
1 clair
2 ls -al
3 vim ~ / somefile.txt
4 histoire
$

Vous pouvez ensuite exécuter n'importe laquelle de ces commandes en utilisant leur index numérique en préfacant l'index par une seule !, comme l'a souligné Mitch :

$! 1

Exécuter la clearcommande. L'historique intégré a de nombreuses fonctionnalités, vous pouvez en voir plus dans les pages man bashet history.

Vous pouvez également spécifier des compensations négatives relatives lorsque vous utilisez l' !indicatif. Par conséquent, si vous souhaitez exécuter à vimnouveau notre liste d'historique ci-dessus , vous pouvez:

$! -2

Ce qui consiste essentiellement à dire à bash d'exécuter la commande que vous avez exécutée "il y a deux commandes". Pour exécuter la commande précédente dans la liste de l'historique, nous pouvons simplement utiliser !!(ce qui est un raccourci pour !-1).

La !désignation ne vous limite pas à spécifier numériquement la commande à exécuter. hayalci a montré que vous pouvez demander bashà exécuter une commande en fonction du texte par lequel elle commence (en utilisant !) ou du texte contenu dans la commande elle-même (en utilisant !?). Encore une fois, en utilisant notre exemple d’historique ci-dessus, si nous voulons exécuter à clearnouveau, il suffit de taper:

$! cl

et appuyez sur Enter. Et qu'en est-il vim? C'est aussi simple que:

$!? some

Le point le plus important de la réponse de hayalci est l’appel à la commande shoptintégrée:

$ shopt -s histverify

Cela permettra à la vérification de l' histoire afin que les commandes qui sont abondés par l' !, !!et !?désignateurs ne sont pas aveuglément exécuté, mais rempli sur la ligne de commande afin de vous assurer qu'ils vont faire aucun mal avant de les exécuter. Ceci est encore plus important lorsque vous exécutez des commandes en tant qu'utilisateur root. Cette option peut être définie dans votre .bashrcfichier de démarrage afin qu'elle le soit chaque fois que vous vous connectez.

Comme cela a déjà été souligné, toutes ces informations peuvent être extraites de la bashpage de manuel . Pour le!, !!, et!? voir les indications de la section 9.3 Extension de l’historique .

Communauté
la source
39
+1 J'utilise Linux depuis plus de 12 ans pour tous les systèmes. Je ne savais pas que ça existait. J'aimerais pouvoir +10, comment ça m'a manqué?
Aiden Bell
1
Sur de nombreux systèmes, appuyer sur la flèche vers le haut a le même effet.
mas
Si quelqu'un consolidait '!', '!!', '!?', 'History | grep ', et' ctrl-r 'dans une réponse complète, je le sélectionnerais
Richard Hoskins le
shoptva dans bashrc, pas bash_profile (ou il ne sera pas activé pour les shells qui ne sont pas des shells de login).
Tobu le
2
De plus, après avoir appuyé sur CTRL + R, vous pouvez utiliser plusieurs fois CTRL + MAJ + R pour revenir à la commande précédente
Gal Bracha
37

Au lieu de cela crtl+R, vous pouvez rechercher l’historique en tapant

!text

Ceci recherchera dans l'historique la commande la plus récente commençant par 'text'.

Mais je vous suggère de mettre cela dans votre .bashrc pour empêcher l'exécution d'une mauvaise commande.

shopt -s histverify

Ceci indique à bash de telle sorte qu'après toute action de l'historique (comme !!:s/prev_text/after_text), il place la ligne résultante à l'invite de commande. Ensuite, vous pouvez revoir ou éditer la commande et appuyer sur Entrée ensuite.

Hayalci
la source
5
Utilisez!? Text pour ré-exécuter la commande la plus récente contenant (par opposition à commencer par) "text".
mark4o
3
Si quelqu'un consolidait '!', '!!', '!?', 'History | grep 'et' ctrl-r 'dans une réponse complète, je le sélectionnerais.
Richard Hoskins
32

Vous pouvez aussi faire:

history | grep "stuff"

il retournerait quelque chose comme

num stuff

alors vous pouvez taper

!num
Mitch
la source
15

Je préfère utiliser l'historique-recherche-arrière sur l'historique de recherche inversée. Le premier vous permet de saisir quelques caractères de la commande, puis d’ appuyer sur la touche de recherche, au lieu d’appuyer d’abord sur la touche de recherche, puis de saisir la chaîne de recherche.

Par défaut, sur mon système, Mp et Mn se lient à des fonctions similaires, mais je préfère lier les touches de direction:

bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
Keith
la source
13

J'ai un très bon alias, h. C'est vraiment juste "history | grep", mais je filtre les entrées précédentes de "commande h" avec "grep -E -v"

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

utilisé comme

h aliases
2003  less .bash_aliases
CurtH
la source
1
Cela peut également être accompli en ajoutant la commande à HISTIGNORE.
Tanenbring
12

Excellent article, Sean! Je mettrais cela dans un commentaire, mais je suis timide sur quelques points de réputation. :-)

Une autre technique connexe et utile est la possibilité d’exécuter une commande précédente tout en modifiant un mot. Supposons que vous avez tapé le nom du répertoire ou que vous vouliez changer le nom du fichier:

$ echo mon nom est bob
je m'appelle Bob
$ ^ bob ^ jordan
echo mon nom est jordan
Mon nom est Jordan

Notez que la commande est développée, remplacée et sortie avant son exécution. Ainsi, si vous exécutez la mauvaise commande, vous pouvez voir ce que pensait bash.

Jordan
la source
6

La navigation dans l'historique à l'aide de la combinaison de touches Ctrl-r étant fastidieuse pour l'OMI, vous pouvez envisager hh :

https://github.com/dvorka/hstr

ce qui rend la navigation beaucoup plus simple, simple et efficace, notamment en exécutant la commande:

entrez la description de l'image ici

Martin Dvorak
la source
Comment l'utiliser? Quelles touches appuyer pour voir cette image?
Nakilon
2
Une fois que vous avez installé hh, vous pouvez soit utiliser la commande hh, soit l’associer à n’importe quel raccourci clavier (généralement Ctrl-r), comme décrit dans la documentation.
Martin Dvorak
il se lie ctrl + rpar défaut maintenant
Alleo
4

À l'invite de commande bash, tapez control-R, puis tapez quelques caractères de la commande souhaitée. La fonction readline de bash recherchera cette commande dans l'historique des commandes.

Une fois la recherche lancée, vous pouvez taper à nouveau control-R pour passer à la commande correspondante suivante.

John1024
la source
3

Si votre shell est configuré pour utiliser des viraccourcis clavier ( set -o viou avoir set editing-mode vidans $HOME/.inputrc), vous effectuez une recherche avec <Esc>/some-command<Return>et cliquez sur n(suivant) ou Shift-n(précédent) pour parcourir l'historique de la ligne de commande.

Fernando Basso
la source
Celui-ci est le plus proche des utilisateurs de vim.
Gabor Marton
2

CTRL+ Rfonctionne très bien, comme l'a suggéré @ John1024, mais est un peu fastidieux si bon nombre de vos commandes récentes sont similaires et que vous souhaitez un moyen rapide de toutes les analyser. Une alternative serait d'utiliser history:

$ history | grep keyword
Mureinik
la source
0

J'aime HSTR mais je n'arrive pas toujours à l'installer. J'ai donc écrit un alias en utilisant fzf qui imite son comportement ( hxpour "history execute")

alias hx='eval $(history | sed "s/^ *[0-9]* *//g" | fzf --tac --tiebreak=index --height=10)'
  • history : bien, obtenez l'histoire
  • sed : supprimer la colonne de numéro de la liste (POSIX)
  • fzf: voici la magie, vous permet d'effectuer une recherche fuzzy de manière interactive dans la liste ou de vous déplacer avec C-Jet C-Kpuis d'exécuter une commande avec Enter.
  • --height : définit le nombre de lignes affichées.
  • --tac : rétablir la liste (plus logique pour un historique)
  • --tiebreak=index : conserve l'ordre de l'historique lorsque fzf met à jour les résultats
Biggybi
la source