met la commande history en ligne de commande sans l'exécuter

57

J'utilise! N où (n) est le numéro de ligne pour l'exécution d'une ligne dans le fichier d'historique que je veux exécuter à l'invite de commande, que je trouve via history | less.

Mais il existe un événement d’historique de ligne de commande que je souhaite modifier manuellement. Comment puis-je insérer dans la ligne de commande un contenu d’historique des événements sans qu’il s’exécute afin que je puisse modifier puis appuyer sur retour?

Meilleur,

Vass
la source

Réponses:

71

Pour demander que la commande soit imprimée plutôt qu'exécutée après la substitution de l'historique, ajoutez le :p modificateur , par exemple !42:p. La commande résultante sera également entrée dans l'historique, vous pourrez donc appuyer sur Uppour la modifier.

Si vous avez l' histverify option set ( shopt -s histverify), vous aurez toujours la possibilité de modifier le résultat des substitutions d'historique.

La fonction fcintégrée donne un accès limité à l’extension de l’historique (aucun indicateur de mot) et vous permet de modifier une commande précédente dans un éditeur externe.

Vous pouvez utiliser !prefixréférence à la dernière commande commençant par prefixet !?substringà la dernière commande commençant par substring. Lorsque vous savez ce que vous recherchez, cela peut vous faire gagner beaucoup de temps history | less.

La recherche incrémentielle est un autre moyen de rechercher dans l'historique précédent: appuyez sur Ctrl+ Ret commencez à entrer une sous-chaîne de ce que vous recherchez. Appuyez sur Ctrl+ Rpour revenir à l’occurrence précédente de la chaîne de recherche et sur Ctrl+ Ssi vous êtes allé trop loin. La plupart des touches autres que Ctrl+ R, Ctrl+ S, Backspaceet les caractères ordinaires fin à la recherche incrémentale et ont leur effet habituel (par exemple les touches fléchées pour déplacer le curseur dans la ligne que vous avez atteint, Enterpour exécuter la commande).

Gilles, arrête de faire le mal
la source
Il y a une faute de frappe dans votre premier exemple ...
pbm
9
Vous devrez le faire stty -ixonavant que Ctrl-s ne fonctionne.
Dennis Williamson
@ Dennis: Wow, les émulateurs de terminaux modernes ne font pas cela par défaut? <test> Vous avez raison, même gnome-terminal dans Ubuntu a le contrôle de flux!
Gilles, arrête de faire le mal
Je ne sais pas pourquoi ils le font encore. Il est impossible d'attraper quelque chose pendant le défilement. Au moment où vous appuyez sur Ctrl-s, vous avez à nouveau une invite. Et les connexions série lentes appartiennent pour la plupart au passé.
Dennis Williamson
@ Le propos de Dennis Ctrl-sest important, sinon on reste bloqué comme moi .
imz - Ivan Zakharyaschev
15

Un autre petit: Alt+#

commente la ligne en cours et la déplace dans la mémoire tampon de l'historique.

Ainsi, lorsque vous assemblez une ligne de commande et que vous devez émettre une commande provisoire pour trouver un fichier, par exemple, il vous suffit d'appuyer sur Alt+ #, d'émettre l'autre commande, de remonter dans l'historique, de supprimer le commentaire et de continuer.

Rahul Patil
la source
2
En outre Esc, #fonctionne
Steven Penny
et vous pouvez taper sur un mac (maintenez les touches shift, appuyez sur Echap et # ensemble), contrairement à l'autre combo de ket (fn + alt + shift + #) ;-)
0xF2
7

Vous pouvez utiliser l’espace magique pour développer l’histoire avant de taper enter. Dans votre .inputrc, mappez l’espace vers l’espace magique:

$if Bash
     Space: magic-space
$endif

Désormais, chaque fois que vous tapez un espace après une spécification d'historique, celui-ci sera immédiatement développé, ce qui est pratique si vous souhaitez également le modifier!

Cascabel
la source
7

Examinez la history-expand-linecommande, liée à Alt+^par défaut. Cela élargira la ligne sur place que vous pourrez ensuite éditer.

Alex Barrett
la source
4

En utilisant Ctrl+rvous pouvez rechercher l'historique:

pbm@tauri ~ $ 
(reverse-i-search)`xran': xrandr -o normal

Toute commande trouvée peut être modifiée ...


Je pense que j'ai trouvé exactement ce dont vous avez besoin: exécuter shopt -s histverifyet la prochaine fois que vous souhaitez utiliser la !ncommande ne sera pas exécutée mais seulement mise en ligne de commande ...

pbm
la source
Vous devez exécuter une commande avant de pouvoir la rechercher avec Ctrl + r, pas ce que Vass demande.
Phunehehe
1
Je ne comprends pas comment cela ne fait pas ce qu'il demande. J'ajouterais que si vous souhaitez d'abord modifier la commande avant de l'exécuter, vous pouvez simplement appuyer sur TAB une fois que vous avez trouvé la bonne commande.
Steven D
2
La procédure serait donc la suivante: (1) Ctrl + r, (2) tapez jusqu'à ce que vous trouviez la commande, (3) TAB, (4) la commande d'édition, (5) ENTER.
Steven D
1
@phuenhehe: "Mais je souhaite modifier manuellement un événement de l'historique de la ligne de commande"
pbm
1
Ne !n:pfonctionnera pas ?
alex
1

J'ai souvent voulu cela. Quand j'ai utilisé csh (et tcsh), j'avais un idiome:
!:88*:p

Cet idiome insère "du mot 88 au dernier mot" de la commande précédente au point où vous tapez sur la ligne de commande actuelle, qui est généralement la fin. En csh, ce n'est pas une erreur pour une telle expression de ne produire aucun mot. Autrement dit, il n'est pas nécessaire que le mot 88 soit suivi d'un mot. S'il n'y a pas de mot 88, cela n'ajoute aucun mot à la fin de la commande en cours de saisie, puis insère la ligne de commande résultante dans l'historique sans exécution.

Comme vous le savez probablement,
*! (comme !! et! -1) est la commande précédente;
*: 88 est le mot 88 (le premier mot - généralement la commande - vaut zéro) et csh exigerait qu'un tel mot existe, mais ...
*: 88 * correspond à tous les mots commençant au mot 88, puis csh n'exige pas que la parole existe;
*: p signifie imprimer, mais n'exécute pas la ligne de commande.
Avec ou sans: p, la ligne de commande est ajoutée à l'historique des commandes.

"Pourquoi 88?" vous vous demandez? Parce que c'est la même clé que le * dont j'ai besoin. Si vous avez des commandes aussi longues, peut-être!: 888 *: p est ce dont vous avez besoin. Désolé, cela ne fonctionne pas avec bash autant que je sache. Bash dira simplement bash: :88*: bad word specifier

Fait amusant: votre commande n'a généralement pas besoin d'être la première.
> /tmp/foo echo My command is word 3
est valide dans bash et csh.

W Dean Stanton
la source
Puisque la question est marquée pour bash, il peut être intéressant de commencer par dire que votre solution ne fonctionne que dans (t) csh.
dimanche
0

J'utilise normalement Ctrl+ rpour rechercher, puis Ctrl+ epour aller à la fin de la ligne sans exécuter.

nikc
la source
déjà mentionné
Jeff Schaller
@JeffSchaller Je ne le vois pas. Je vois la référence CTRL + R. Nulle part je ne vois le CTRL + E qui est la pièce manquante du puzzle dans les messages ci-dessus.
nikc