Comment exécuter des commandes consécutives de l'historique?

49

Supposons que je veuille exécuter une séquence de quatre commandes que j'ai déjà exécutées. Si le premier est 432 dans l'historique des commandes, je pourrais faire:

$ !432; !433; !434; !435

Je suis curieux de savoir s'il existe un moyen plus efficace d'y parvenir.

Eric Wilson
la source
1
Affichant pas cela comme une réponse parce qu'il n'a pas d' exécuter les commandes, mais vous pouvez taper history -p \!43{2..5}d'imprimer des commandes 432 par 435 au terminal, adapté pour la copie ultérieure / coller.
Wildcard

Réponses:

48

Si cela fait référence à des commandes exécutées récemment, un moyen plus efficace consiste à les référencer avec des nombres négatifs:

!-4; !-3; !-2; !-1

De plus, une fois que vous aurez fait cela, votre dernière entrée d'historique contiendra toute la chaîne de commandes afin que vous puissiez la répéter avec !!.


Edit: Si ce n’est déjà fait, familiarisez-vous avec la superbe fonction intégrée fc, mentionnée par Gilles . (Utilisez help fc.) Il s’avère que vous pouvez également utiliser des nombres négatifs pour pouvoir faire la même chose que ci-dessus en utilisant

eval "`fc -ln -4 -1`"

Cela a cependant une mise en garde: après cela, la evalligne est stockée dans l'historique en tant que dernière commande. Donc, si vous recommencez, vous tomberez dans une boucle!

Une méthode plus sûre consiste à utiliser le fcmode de fonctionnement par défaut : transférer la plage de commandes sélectionnée vers un éditeur et les exécuter une fois que vous en sortez. Essayer:

 fc -4 -1

Vous pouvez même inverser l'ordre de la plage de commandes: fc -1 -4

rozcietrzewiacz
la source
Je viens de lire ce que j'avais écrit ... LOL. En fait, je ne suis pas sûr de pouvoir réinvoquer ( réinvoquer peut - être?), Mais merci de l'avoir dit :) J'apprécie toujours les corrections.
rozcietrzewiacz
Le mot Scrabblefinder.com ne veut pas dire que réinvoquer est valide. Je ne peux pas obtenir plus définitif que cela. :)
BentFX
1
Avec une bonne réponse comme celle-ci (+1), peu importe la façon dont vous l'épelez; d'autant plus qu'aucune forme orthographique n'apparaît dans 3 dictionnaires anglais majeurs : Oxford, Camgridge, Merriam-Webster (j'irais pour le trait d'union)
Peter.O
34

Pour afficher une gamme de commandes dans l'historique, utilisez la fccommande intégrée :

fc -ln 432 435

Pour les exécuter à nouveau:

eval "$(fc -ln 432 435)"
Gilles, arrête de faire le mal
la source
4
Très agréable. Je suis curieux cependant, pourquoi man fcne me donne rien. Que veut dire fc? Quelles sont les autres options?
Eric Wilson
2
@ Eric Wilson ... tapez help fc... et aussi help help.... help: help [-dms] [pattern ...] Affiche des informations sur les commandes intégrées.
Peter.O
Je viens de revenir ici, à la recherche de votre réponse. Ceci est vraiment un grand intégré! Surtout quand vous avez sa fonctionnalité par défaut - appeler un éditeur pour modifier une plage de commandes à rejouer. Merci Gilles.
rozcietrzewiacz
1
Sans -ldrapeau, il exécutera sans avoir besoin de la perversité eval.
Bernhard
1
@EricWilson Une recherche sur Google m'a conduit au livre "Unix en bref" qui fcsignifie "find command" ou "fix command".
Slothworks
10

Il existe un moyen intéressant et alternatif d'exécuter plusieurs commandes en séquence à partir de l'historique Bash:
au lieu d'utiliser substitut d'historique ( !432ou !-4), vous pouvez parcourir l'historique avec Ctrl+ r, et une fois que vous avez trouvé la première commande à utiliser run, tapez Ctrl+ o( operation-and-get-next ) à la place de la returnclé.
Ceci lancera la commande et proposera la suivante à partir de l'historique. Vous pouvez appuyer Ctrl+osur autant de fois que vous le souhaitez et mettre fin à la séquence, soit returnpour une dernière fois, soit Ctrl+cpour vous arrêter sans la lancer.

Cyril Chaboisseau
la source
Hmm, après que je l'ai frappé, Ctrl-oil ne fait que sortir un littéral ^oet me brise (reverse-i-search). Peut-être y a-t-il un autre paramètre impliqué.
Ciro Santilli a annoncé le
8

Pour exécuter les commandes immédiatement plutôt que de les éditer, voici une version syntaxiquement plus fine de la réponse de Giles à l'aide de eval :

fc -e: 432 435

L'argument deux-points à -e est le bash noop, ce qui a pour effet de sauter l'étape "ouvrir dans un éditeur" que fc veut. En outre, l'historique (récent) contiendra les commandes réelles de l'historique, plutôt que l'instruction eval.

utilisateur1543542
la source
0

fc pour la boucle et xsel

Cela fonctionne bien lorsque je veux concaténer et réexécuter les n dernières commandes plusieurs fois:

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in `seq "$from" -1 "$(($to + 1))"`; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

Ensuite:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

Ou pour des commandes plus volumineuses nécessitant éventuellement des modifications:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
Ciro Santilli 改造 中心 六四 事件
la source