2009-11-13 16 views
1

Puisque le contrôle de croisière est plein de bugs qui ont gaspillé toute ma semaine, j'ai décidé que les scripts shell que je possède sont plus simples et donc meilleurs.Comment puis-je utiliser des codes de sortie pour exécuter séquentiellement des scripts shell?

Voici ce que j'ai jusqu'à présent

svn update /var/www/k12/ 
#svn log --revision "HEAD" /var/www/code/ | head -2 | tail -1 | awk '{print $1}' > /var/www/path/version.txt 

# upload the files 
rsync -ar --verbose --stats --progress --delete --exclude=*.svn /var/www/code/ example.com:/home/path 

# bring database up to date 
ssh example.com 'php /path/tasks/dbrefactor.php' 

# notify me 
ssh example.com 'php /path/tasks/build.php' 

La seule chose est l'autre jour je l'ai changé les chemins et oublié de mettre à jour l'appel rsync. En conséquence, l'étape «notifiez-moi» s'est déroulée plusieurs fois pendant que je réfléchissais à des choses.

Je sais que dans Linux, vous pouvez faire command1 && command2 et si la commande 1 "échoue" commande2 ne fonctionnera pas, mais comment puis-je observer les codes de sortie "échec/succès" à des fins de débogage. Certains des scripts que j'ai écrits moi-même et je suis sûr que je vais devoir faire quelque chose de spécial.

Répondre

2

Le code de sortie d'un processus précédent se trouve être en $? droite variable après son exécution. Habituellement (ce n'est pas obligatoire, mais c'est la convention que tout le monde suit) le code de sortie d'une commande réussie sera égal à 0, et toute autre valeur signifie une erreur.

Rappelez-vous des mises en garde! L'un d'eux est que, après ces commandes:

svn log --revision "HEAD" /var/www/code/ | head -2 | tail -1 | awk '{print $1}' 
echo "$?" 

le résultat nul serait très probablement retourné, parce que dans le $? le code retour awk est contenue. Pour éviter cela, réglez l'option pipefail quelque part au-dessus du code:

set -o pipefail 1 
+0

Merci!Je vais tester cela sur –

+1

Josh, puisque vous avez plus de 15 réputation, vous pourriez vouloir et être en mesure de "voter" pour les réponses que vous avez aimé et/ou trouvé utile - essayez les boutons près des grands nombres. –

1

La valeur de retour de la dernière commande est enregistrée dans la variable $?. Vous pouvez l'utiliser pour déterminer la commande à exécuter ensuite. Overview of special variables.

+0

Merci pour le lien utile –

1

Je pense que $? contient le dernier code de sortie

if [[ -z $? ]] 
then 
    # notify me 
    ssh example.com 'php /path/tasks/build.php' 
fi 
4

La meilleure option, surtout pour les scripts sans surveillance, est de définir l'option shell -e:

#!/bin/sh -e 

ou

set -e 

Cela le shell arrête l'exécution si une commande (non testée) se termine avec un code d'erreur non nul.

 
      -e  Exit immediately if a simple command (see SHELL GRAMMAR 
        above) exits with a non-zero status. The shell does not 
        exit if the command that fails is part of an until or 
        while loop, part of an if statement, part of a && or || 
        list, or if the command's return value is being inverted 
        via !. A trap on ERR, if set, is executed before the 
        shell exits. 
+0

Comment afficher le code d'erreur à des fins de test. –

+0

Le code de sortie (non nul) détecté par le shell sera la valeur de retour du shell lorsqu'il reviendra. Donc, vous utiliseriez '$?' Après la sortie du script shell. –

0

je suggère que vous pouvez utiliser la sortie non nul aux points où l'échec est prévu et avant l'étape de traitement plus vous vérifierez si [$ ? -neq 0] alors il y a un échec.


Le $? retournera toujours un nombre non nul si le dernier processus ne s'est pas exécuté avec succès.