Attendre l'utilisation des commands sous Linux?

#!/bin/bash function back() { sleep $1 exit $2 } back $1 $2 & b=$! if `wait $!`;then echo success else echo failure fi 
 bash-3.00# ./back 300 0 failure bash-3.00# ./back 300 1 failure 

J'attendais le success comme statut de sortie quand j'envoie 0, mais je suis toujours en train d' failure .

En outre, wait n'attend pas pendant 300 secondes. Au lieu de cela, je reçois le message immédiatement. Je suppose que $! est l'enfant immédiat de $$ dans mon script. N'est-ce pas?

Est-il possible de capturer l'état de sortie de wait comme exit_status=$(wait $!) ?

 if ! ((exit_status));then echo sucess else failure fi 

Le problème est que vous wait dans un sous-shell:

 if `wait $!`;then 

Parce que wait est un builtin, pas une command, il fonctionne sur le sousshell , pas votre shell actuel.

La sortie que vous verriez mais ne l'est pas est:

 wait: pid 12344 is not a child of this shell 

… avec un statut de return de 1.

Pour effectuer votre test, vous devrez le faire sans utiliser un sous-shell.

 #!/bin/bash function back() { sleep $1 exit $2 } back $1 $2 & b=$! wait $b && echo success || echo failure 

Cela donne le résultat que vous attendez et attend aussi longtime que vous le souhaitez:

 $ time ./test.sh 3 0 success ./test.sh 3 0 0.00s user 0.01s system 0% cpu 3.012 total $ time ./test.sh 3 1 failure ./test.sh 3 1 0.00s user 0.01s system 0% cpu 3.012 total 

Vous pouvez vérifier le statut de sortie de n'importe quelle command avec $? :

 $ /bin/true $ echo $? 0 $ /bin/false $ echo $? 1 

Il y avait quelques autres erreurs dans votre script. Votre #! ligne était malformé, que j'ai réparé. Vous affectez $! à $b , mais n'utilisez pas $b .

Retirez les points d'appui.

En l'état, vous exécutez wait dans un sous-shell, qui n'a pas access aux tâches du shell parent, donc il échouera immédiatement.


Si vous voulez le statut de sortie, obtenez la valeur de $? immédiatement après l'attente.

 command_here & wait status=$? 

La suppression des points d'appui rendra le programme fonctionnel, mais pas entièrement en raison des raisons déjà identifiées. Il est vrai que l' wait échoue immédiatement car elle s'exécute dans un sous-shell et ne peut pas accéder aux process de son parent, mais le programme ne s'exécutera pas comme prévu, même si vous avez utilisé une command qui a fonctionné.

L'instruction if exécute un programme et vérifie si son état de sortie est zéro ou non. Lorsque vous utilisez des backticks, l'instruction if prendra la sortie du process, essayez de l'exécuter en tant que programme, puis utilisez le code de sortie pour ce process. Le programme n'échoue donc pas car l' wait échoue, mais échoue car l' wait ne produit aucune sortie.

Vous pouvez faire fonctionner le script en utilisant l' echo dans les backticks:

 if `echo wait $!`; then echo success else echo failure fi 

Ou juste enlever les points d'appui; plus facile pour tout le monde.