68 votes

Exécuter une commande après l'autre, même si je suspends la première (Ctrl-z)

Je sais que dans bash, je peux exécuter une commande après l'autre en les séparant par des points-virgules, par exemple

$ command1; command2

Ou si je veux seulement command2 pour fonctionner uniquement si command1 réussit, en utilisant && :

$ command1 && command2

Cela fonctionne, mais si je suspends command1 en utilisant Ctrl-z Dans le premier cas, il s'exécute command2 immédiatement, et dans le second cas, il ne l'exécute pas du tout. Comment puis-je exécuter des commandes en séquence, tout en étant capable de suspendre la première commande, mais de ne pas faire exécuter la seconde tant que je ne l'ai pas redémarrée (avec fg ) et elle se termine ? Je préférerais quelque chose d'aussi simple à taper que possible, car je voudrais faire cela de manière interactive. Ou peut-être dois-je simplement définir une option quelque part.

Au fait, quel est le terme approprié pour ce que Ctrl-z fait ?

2 votes

command1; command2 devrait faire exactement ce que vous voulez. En ce qui concerne la terminologie, Ctrl-Z suspend le processus.

0 votes

Eh bien, ce n'est pas le cas. J'utilise la version bash 4.2.8(2)-release sur Mac OS X 10.8 dans iTerm2.

0 votes

Merci pour la terminologie. Je vais mettre à jour la question pour l'utiliser.

94voto

NPE Points 169956

Les éléments suivants devraient suffire :

(command1; command2)

Notez les parenthèses ajoutées.

5 votes

Génial ! Maintenant, est-ce que vous ou quelqu'un d'autre peut expliquer pourquoi il se comporte comme il le fait pour ces trois cas ( command1; command2 , command1 && command 2 y (command1; command2) ) ?

2 votes

En fait, je ne suis pas sûr. Peut-être que quelqu'un pourrait nous éclairer tous les deux.

44 votes

Techniquement, vous ne suspendez pas les processus avec Control-z, vous suspendez emplois . Avec command1; command2 le travail actif est juste le processus command1 lorsque vous appuyez sur Control-z, il est donc suspendu et le travail suivant ( command2 ) commence. Avec (command1; command2) Le travail actif est constitué de la sous-séquence qui exécute les deux commandes, de sorte que la sous-séquence entière est suspendue par Control-z. Vous pouvez le confirmer en exécutant la commande jobs après avoir suspendu chacun d'eux.

11voto

cdarke Points 8020

Dans Bash, lorsque vous placez un travail en arrière-plan (en utilisant CTRL+Z ou &), il n'attend pas que le travail se termine et donne un code de sortie de zéro (succès). C'est ce que vous avez observé, et c'est documenté dans le document man pages.

Le comportement du "AND" logique, &&, est qu'il teste de gauche à droite. Chaque partie doit être réussie, donc si la première n'est pas réussie, la seconde ne sera pas exécutée. Ainsi, avec &&, il exécute les commandes de gauche à droite jusqu'à ce que l'une d'entre elles échoue. La définition du succès est un code de sortie ($ ?) égal à zéro.

Comparez cela avec le "OU" logique, ||, qui exécute les commandes de gauche à droite jusqu'à ce que l'une d'entre elles soit sélectionnée. travaux .

L'explication de la solution de sous coquille donnée par @NPE peut également être trouvée dans le man pages :

Les commandes composées et les séquences de commandes de la forme 'a ; b ; c' ne sont pas gérées de façon élégante lorsque la suspension d'un processus est tentée. Lorsqu'un processus est arrêté, le shell exécute immédiatement la commande suivante dans la séquence. Il suffit de placer la séquence de commandes entre parenthèses pour la forcer dans un sous-shell, qui peut être arrêté comme une unité.

Le terme adéquat pour CTRL+Z est la fonction suspendre personnage, toujours selon le man pages :

Taper le caractère de suspension (typiquement ^Z, Control-Z) alors qu'un processus est en cours d'exécution entraîne l'arrêt de ce processus et le retour du contrôle à bash.

(Désolé de citer le man pages tellement, mais ils sont vraiment vos amis et valent la peine d'être lus)

Si vous regardez stty -a vous verrez quelque chose comme ceci :

susp = ^Z; 

Vous pouvez donc le modifier, d'où l'expression "généralement". Mais ne le faites pas, vous risqueriez d'embrouiller tout le monde. Le pilote de terminal émet un signal SIGTSTP qui est piégé par Bash.

0 votes

Je ne comprends toujours pas le comportement de &&. La suspension du processus entraîne-t-elle un retour non nul ?

0 votes

De quelles pages de manuel s'agit-il ? Je me suis dit que la réponse devait s'y trouver, mais je n'avais aucune idée de par où commencer.

0 votes

&& se joint à deux pipelines et chaque pipeline est un travail distinct. (Notez que le pipeline est une ou plusieurs commandes jointes par un bouton | ce qui signifie command1 est techniquement un pipeline unique à une seule commande).

-2voto

user3057624 Points 1

&& Devrait obliger à terminer la commande avant de passer à la suivante, si je comprends bien. Un programme ne devrait renvoyer un code 0 que si le corps principal du code/de la commande en cours d'exécution a été mené à bien. Ainsi, && attendrait un code 0 de la part du programme qui le précède (indiquant que le programme aurait dû se terminer et se terminer). Cela signifie que si le programme est exécuté avec && après avoir été suspendu, il ne faut pas s'attendre à ce que la commande suivante s'exécute avant que le programme précédent ait terminé son exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X