Rechercher une commande précédente avec le préfixe que je viens de taper

67

Nous pouvons utiliser les flèches haut et bas pour naviguer dans l'historique des commandes.

Dans certains IDE, tels que Matlab, si nous saisissons quelque chose, puis que nous appuyons sur les touches fléchées, nous ne faisons défiler que les commandes d'historique commençant par ce que nous avons entré. C'est vraiment pratique, mais dans un terminal shell, cela ne fonctionne pas.

Est-il possible d'obtenir une fonction similaire dans un terminal shell? Et d'autres astuces pour améliorer l'efficacité d'utilisation du terminal?

Lee
la source
Vous pouvez simplement utiliser un shell fournissant une telle fonctionnalité, par exemple fish;)
yoann
@yoann vous supposez que bash ne l'est pas. Via readline, il n’est tout simplement pas accessible par défaut.
Muru
@muru Je connais CTRL + R sous bash, et la réponse d'Egmont fournit un moyen élégant de le faire avec Page Up / Page Down. Y a-t-il cependant moyen de le faire avec les touches fléchées?
Yoann
1
@yoann Découvrez unix.stackexchange.com/a/76591/70524 . Au lieu de \e[5~et \e[6~, l' utilisation \e[A, \e[B.
muru

Réponses:

95

Ce que vous cherchez, c'est CtrlR.

Tapez CtrlRpuis tapez une partie de la commande souhaitée. Bash affichera la première commande correspondante. Continuez à taper CtrlRet bash fera défiler les commandes correspondantes précédentes.

Pour rechercher dans l'historique, tapez CtrlSplutôt. (Si CtrlScela ne fonctionne pas ainsi pour vous, cela signifie probablement que vous devez désactiver le contrôle de flux XON / XOFF: pour cela, exécutez stty -ixon.)

Ceci est documenté sous "Recherche" dans man bash.

John1024
la source
1
Ctrl-Qpour quitter l'état gelé, si vous avez déjà frappé Ctrl-Ssans désactiver d'abord le contrôle de flux et bloqué votre terminal.
HongboZhu le
26

Placez-les dans votre ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

Ceux-ci font Page Upet Page Downse comportent comme vous le souhaitez. (Certaines distributions l'ont déjà configuré pour vous.) Personnellement, je trouve ces moyens plus pratiques que Ctrl+ Rou history.

Egmont
la source
C'est le moyen le plus pratique dans toutes les réponses actuelles. Pourriez-vous donner une petite explication sur le mécanisme de travail?
Lee
3
~/.inputrcou /etc/inputrcou le fichier référencé par la variable d'environnement $INPUTRCest le fichier de configuration de l'édition de ligne de toutes les applications utilisant readline, y compris bash (votre shell). Il possède certaines fonctionnalités d'édition de ligne intégrées, notamment les deux suivantes: dans la page de manuel de bash, recherchez l'un de ces mots clés pour en savoir plus. \e[5~/ \e[6~sont les séquences d'échappement générées par les touches Page Up / Down dans la plupart des émulateurs de terminaux; pour le voir, lancez la catcommande puis appuyez sur ces touches (l'octet d'échappement est représenté dans le terminal sous la forme ^[, dans inputrc as \e).
egmont
L'exemple de votre question initiale indique que les touches Haut / Bas fonctionnent de cette manière dans Matlab. Il serait intéressant de voir ce qui s’est passé si vous avez placé la séquence de haut en bas dans inputrc et affecté à cette action; cela fonctionnerait-il correctement ou aurait-il des effets secondaires désagréables car il est en conflit avec leur comportement par défaut. Je ne sais pas, je serais heureux d'entendre vos conclusions si vous expérimentez avec cela.
egmont
Quand je le fais echo $INPUTRCest vide. J'utilise Ubuntu 14.04
JorgeeFG le
2
"\e[A": history-search-backward"\e[B": history-search-forward
Personnellement,
9

En plus de l’historique de ^ i / search:

alt.insère le dernier "mot" de la commande précédente au curseur. Répétez cette opération pour obtenir le dernier mot des commandes plus anciennes. (Mais notez qu'une fin &compte comme le dernier mot pour les commandes d'arrière-plan).

C'est super pratique pour mkdir foo, cdalt-dot. Encore plus vite que la flèche haut, ^ a, alt-d (supprimer mot avant), cd.

Pour obtenir l’avant-dernier mot, utilisez esc - 2 alt+.(c’est -à- dire, utilisez un argument numérique de style emacs alt+.. Les décomptes négatifs à partir de la fin, les décomptages positifs à partir du début.) Mais c’est généralement plus difficile que ça vaut la peine; à un moment donné, il est plus rapide d’atteindre la souris et de copier / coller, ou encore une flèche vers le haut et une partie de celle-ci (voir ci-dessous).


Si votre terminal est bien configuré / correctement, ctrl-gauche et ctrl-droite iront en arrière / en avant par mots. Sinon, au moins, alt-b et alt-f feront la même chose.


ctrl- / est une annulation. Vous pouvez utiliser la répétition automatique pour supprimer des mots de manière beaucoup plus efficace si vous pouvez annuler un dépassement de temps.


Le kill / ring, qui fonctionne comme dans Emacs, permet un mélange / une correspondance plus puissant des commandes. Ctrl-y pour coller le dernier ctrl-w / ctrl-u / ctrl-backspace / alt-d. alt-y pour parcourir le texte ancien tué.

Plusieurs ctrl-w ou quoi que ce soit dans une rangée font sur l'entrée kill-ring. Utilisez les flèches gauche et droite ou quelque chose d'autre pour séparer l'entrée si vous souhaitez supprimer deux éléments et ne les coller que plus tard.

En combinant tous ces éléments, vous pouvez

  • commencer à taper une commande
  • Ctrl-r pour revenir à une ancienne commande et en récupérer une partie avec control-w ou similaire.
  • esc-r ou alt+rpour rétablir sa configuration antérieure avant d'en supprimer une partie.
  • alt - >pour aller à la fin de l’histoire (c’est-à-dire la flèche vers le bas), pour revenir à la commande dans laquelle vous étiez.

Autres conseils d'utilisation interactive:

Activer shopt -s globstar, donc vous pouvez faire **/*.c(récursif, y compris le répertoire en cours). Parfois pratique pour une utilisation interactive, mais en général find -name '*.c' -exec foo {} +c'est mieux.

Si vous écrivez des scripts bash, il vous sera utile d' shopt -s extglobactiver également vos shells interactifs. Vous trouverez parfois une utilisation pour des choses comme *.!(c|h)faire correspondre des fichiers qui ne se terminent pas par .c ou .h.

Trouvez des alias que vous aimez pour ls -l, lesset tout ce que vous faites beaucoup. ( cp -i, mv -iet rm -Isont gentils. Ne prenez pas l'habitude de compter sur eux pour faire une requête sélective. GNU rm's - Je demande une fois tous les arguments.)

J'aime alias m=less(m pour "plus"). J'ai lessconfiguré avec ,et .lié au fichier précédent / suivant ( lesskey). La valeur par défaut est une séquence de touches multiples qui ne peut pas être utilisée avec la répétition automatique.


J'aime tout faire à l'intérieur de l'écran GNU. Je trouve qu'il est plus facile de garder une trace des fenêtres d'écran numérotées qu'un chargement d'onglets dans Konsole (ou tout autre émulateur de terminal que j'ai essayé). Si vous ne le savez pas déjà screen, apprenez tmux car il est plus récent et moins cruel.

Pour obtenir quelque chose comme la fonctionnalité d'ouvrir un nouveau shell avec le même cwd qu'un autre shell, j'utilise un hook personnalisé pour cd / pushd / popd qui me permet de créer un cd dans le répertoire utilisé par cds 8mon shell dans la fenêtre d'écran 8. Cela fonctionne même pour les shells en dehors de la session d'écran, à condition qu'il n'y ait qu'une seule session d'écran.

Peter Cordes
la source
Le mien ne semble pas être "correctement configuré". Un grand nombre des raccourcis que je vois ici ne fonctionnent pas, j'utilise actuellement Terminal Server d'Ubuntu 14.04. Comment puis-je le configurer?
JorgeeFG
@ JorgeeFG: Je pense que cela a fonctionné pour moi dès la première utilisation avec gnome-terminalUbuntu 14.04, avant de passer à KDE. L'option appropriée se trouve dans les paramètres de votre terminal, préfixe-esc par rapport à bit fort, et peut-être d'autres paramètres. Certaines ne fonctionnent pas parfaitement pour moi avec ssh. (par exemple, ctrl gauche / droite mugge le code d'échappement de la touche fléchée, et j'apparais 5Dlittéralement)
Peter Cordes
7

Ajoutez les lignes suivantes à votre ~/.inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward

Ceci est similaire à la réponse de egmont, mais au lieu d'utiliser Page Up et Page Down, il utilise les séquences d'échappement pour Arrow Up et Arrow Down. Cette méthode est beaucoup plus pratique à utiliser sur un Mac.

John Slavick
la source
4

J'ai toujours tendance à configurer mes machines avec une valeur HISTSIZE élevée afin qu'il conserve une liste d'historique plus longue, ainsi que HISTTIMEFORMAT avec la valeur d'horodatage afin que je puisse voir à quel moment la commande a été exécutée.

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "
Alpha01
la source
3

Le moyen que j'utilise habituellement est de combiner la historycommande avecgrep

C'EST À DIRE:

history | grep <command im looking for>

Cela affichera un historique numéroté des commandes que vous avez tapées contenant cette commande, vous pouvez ensuite utiliser:

!<number listed in history command>

refaire cette commande.

C'EST À DIRE:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

suivi par: !571

va répéter history | grep history

Sauce
la source
1
CR = beaucoup mieux + beaucoup plus sûr
PSkocik
1
Peut-être que personnellement, je trouve qu'une histoire transmise à grep est un moyen plus rapide de trouver la plupart des commandes. En ce qui concerne Safer, je ne suis pas sûr de ce que vous entendez, quels sont les risques inhérents à l'utilisation de l'historique en raison d'une recherche dans cR?
Sauce
2
@Gravy Je pense que PSkocik signifie que la !substitution d'historique est moins sûre.
derobert
3
@Gravy Les risques inhérents seraient d'obtenir accidentellement la mauvaise ligne. Aucune idée de la raison pour laquelle votre terminal est gelé, sauf si vous avez utilisé Control-S et que le contrôle de flux xon / xoff est activé (souvent la valeur par défaut). Si tel est le cas, Control-Q le ramènera.
derobert
1
Je suis d'accord avec @PSkocik, cr est beaucoup mieux car il est plus facile de modifier la ligne d'historique plutôt que de la réexécuter de la même manière. Exécuter à nouveau exactement la même commande est un cas simple de ce que vous pouvez faire pour gagner du temps à retaper des variations sur des lignes uniques complexes ou pour compléter un fichier différent par un long chemin. Voir ma réponse.
Peter Cordes
1

J'ai utilisé quotidiennement 4 astuces (et quelques autres) dans mon terminal bash:

  • Exécute la dernière commande: !!

  • Exécutez la commande N de l'historique: !N

  • Imprimer la dernière commande en commençant par le préfixe de l'historique: !prefix:p

  • Exécutez la dernière commande en commençant par le préfixe de l'historique: !prefix

Nolwennig
la source
1

Si vous pouvez l'utiliser à la zshplace de bashvous, utilisez oh-my-zsh pour cela.

Il contient la flèche vers le haut dans la navigation dans votre historique de commandes. Il permet également cette même navigation lorsque vous avez déjà tapé du texte (comme Mathlab).

edit: Il contient également d'autres éléments axés sur les développeurs, tels que des alias et des thèmes. Ces extras rendent la distribution plus grande et plus complexe à utiliser.

https://github.com/robbyrussell/oh-my-zsh

utilisateur9869932
la source
1
oh-my-zshcontient des tonnes de choses. Vous pourriez aussi bien dire: Cette fonctionnalité exacte est incluse dans cette distribution, lorsque vous avez simplement besoin d’un paramètre ou d’une application spécifique.
muru
J'ai édité le message: j'ai averti qu'il est plus gros qu'une simple application.
user9869932
1

Ajoutez l'alias suivant à ~ / .bashrc

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

Utilisation: h fireme donnera une liste de commandes contenant du feu . ou h ^fireva me donner une liste de commandes commencent par le feu .

Ceci est utile lorsque je souhaite afficher une série de commandes en même temps.

Au fait, '"'"'c'est moche, mais je ne pouvais pas trouver d'autres moyens d'éviter les guillemets simples.

Hosi Golden
la source
fyi - h="history | awk '{\$1=\"\"; print}'devrait fonctionner. alternativement, créez une fonction et appelez-la.
DarkHeart
merci DarkHeart, mais j'ai essayé votre code, mais cela n'a pas fonctionné dans mon environnement, peut-être y a-t-il quelque chose de différent dans le mien
Hosi Golden