web-dev-qa-db-fra.com

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

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

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

Je suis curieux, existe-t-il un moyen plus efficace d'accomplir cela?

50
Eric Wilson

S'il 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 l'avez fait, votre dernière entrée d'historique contiendra toute la chaîne de commandes, vous pouvez donc la répéter avec !!.


Edit: Si vous ne l'avez pas déjà fait, familiarisez-vous avec la grande fonction intégrée fc, mentionné par Gilles. (Utilisation help fc.) Il s'avère que vous pouvez également utiliser des nombres négatifs avec lui, vous pouvez donc 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 ligne eval est stockée dans l'historique en tant que dernière commande. Donc, si vous exécutez à nouveau, vous tomberez dans une boucle!

Une manière plus sûre de procéder consiste à utiliser le mode de fonctionnement par défaut fc: transférer la plage de commandes sélectionnée vers un éditeur et les exécuter une fois que vous en avez quitté. Essayer:

 fc -4 -1

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

49
rozcietrzewiacz

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

fc -ln 432 435

Pour les exécuter à nouveau:

eval "$(fc -ln 432 435)"

Il existe une manière agréable et alternative d'exécuter un certain nombre de commandes en séquence à partir de l'historique de Bash:
au lieu d'utiliser le substitut d'historique (!432 ou !-4), vous pouvez rechercher dans l'historique avec Ctrl+r, et une fois que vous avez trouvé la première commande que vous souhaitez exécuter, appuyez sur Ctrl+o (opérer et aller de l'avant) à la place du return clé
Cela va lancer la commande et proposer la suivante de l'historique. Vous pouvez frapper Ctrl+o autant de fois que vous le souhaitez et terminez la séquence avec return pour une dernière, ou Ctrl+c pour arrêter sans le lancer.

10
Cyril Chaboisseau

Pour exécuter les commandes immédiatement plutôt que de les modifier, voici une version syntaxiquement plus fine de Giles répond en utilisant 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" souhaitée par fc. De plus, à présent, l'historique (récent) contiendra les commandes réelles de l'historique, plutôt que l'instruction eval.

8
user1543542

fc pour la boucle et xsel

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

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})"
)

Alors:

$ 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 qui pourraient nécessiter quelques modifications:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh