web-dev-qa-db-fra.com

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, comme

$ command1; command2

Ou si je veux seulement command2 à exécuter 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 exécute command2 immédiatement, et dans le second cas, il ne fonctionne pas du tout. Comment puis-je exécuter des commandes en séquence, tout en pouvant suspendre la première commande, mais ne pas avoir la deuxième exécution avant de l'avoir redémarrée (avec fg) et qu'elle se termine? Je préférerais taper le plus simplement possible, car j'aimerais le faire de manière interactive. Ou peut-être dois-je simplement définir une option quelque part.

À propos, quel est le terme approprié pour ce que Ctrl-z Est-ce que?

66
asmeurer

Ce qui suit devrait le faire:

(command1; command2)

Notez les parenthèses ajoutées.

90
NPE

Dans Bash, lorsque vous placez un travail en arrière-plan (à l'aide de CTRL + Z ou &), il n'attend pas la fin du travail et donne un code de sortie égal à zéro (succès). C'est ce que vous avez observé et cela est documenté dans les pages man.

Le comportement logique de "ET", &&, est qu'il teste de gauche à droite. Chaque partie doit réussir. Par conséquent, si la première échoue, la seconde ne fonctionnera pas. Ainsi, avec &&, les commandes sont exécutées de gauche à droite jusqu'à ce que l'une d'entre elles échoue. La définition de succès est un code de sortie ($?) De zéro.

Comparez cela avec "OU" logique, ||, qui exécute les commandes de gauche à droite jusqu'à ce que l'un d'eux fonctionne.

L'explication de la solution de sous-shell donnée par @NPE est également disponible dans les pages man:

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

Le terme approprié pour CTRL + Z est le caractère suspendre, toujours à partir des pages man:

Taper le caractère de suspension (généralement ^ Z, Control-Z) pendant l'exécution d'un processus provoque son arrêt et renvoie le contrôle à bash.

(Désolé de citer autant les man pages, mais elles sont vraiment vos amis et méritent d'être lues)

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

susp = ^Z; 

Vous pouvez donc le modifier, d'où l'expression "typiquement". Ne faites pas cela cependant, cela déroutera tout le monde. Le pilote du terminal émet un signal SIGTSTP qui est capturé par Bash.

11
cdarke