2010-05-19 7 views
2

J'ai un script bash qui effectue plusieurs opérations sur les fichiers. Quand un utilisateur exécute ce script, il s'exécute avec succès et affiche quelques lignes de texte, mais lorsque j'essaie de le lancer, il y a des problèmes. Il semble fonctionner (je vois une entrée dans cron log montrant qu'il a été lancé) mais rien ne se passe, il ne sort rien et ne fait aucune de ses opérations de fichiers. Il n'apparaît pas non plus dans les processus en cours d'exécution, il semble donc disparaître immédiatement. Après un dépannage, j'ai trouvé que la suppression de "set -e" résolvait le problème, il fonctionne maintenant à partir du système cron sans problème. Donc ça marche, mais je préfèrerais avoir mis -e activé pour que le script se termine s'il y a une erreur. Est-ce que quelqu'un sait pourquoi "set -e" provoque la sortie de mon script?

Merci pour l'aide,
RyanPourquoi l'utilisation de set -e fait-elle échouer mon script lorsqu'il est appelé dans crontab?

+0

Si 'set -e' le fait sortir en cas d'erreur ... cela ne veut-il pas dire qu'il y a une erreur quelque part? –

+0

Le script s'exécute si je l'exécute manuellement. Als, s'il rencontre des problèmes, le code d'erreur devrait être imprimé sur stdout avant qu'il ne se termine. Cela n'arrive pas. – SDGuero

+0

Sauf si vous montrez votre script, nous ne pouvons pas dire quel pourrait être le problème.De plus, à mon avis, 'set -e' ne remplace pas la gestion correcte des erreurs et ne devrait pas être utilisé du tout. –

Répondre

4

Lorsque votre script fonctionne sous Cron, les variables d'environnement et chemin peuvent être réglés différemment que lorsque le script est exécuté directement par un utilisateur. Peut-être c'est pourquoi il se comporte différemment?

Pour tester ceci: créez un nouveau script qui ne fait rien d'autre que printenv et echo $PATH. Exécutez ce script manuellement, en enregistrant la sortie, puis en l'exécutant comme un travail cron, en sauvegardant cette sortie. Comparez les deux environnements. Je suis sûr que vous trouverez des différences ... un shell de connexion interactif aura eu son environnement mis en place en fournissant un ".login", ".bash_profile", ou un script similaire (selon le shell de l'utilisateur). Cela ne se produit généralement pas dans un travail cron , ce qui est généralement la raison pour laquelle un travail cron se comporte différemment de l'exécution du même script dans un shell de connexion .

Pour résoudre ce problème: En haut du script, soit explicitement défini les variables d'environnement et PATH pour correspondre à l'environnement interactif, ou la source « .bash_profile », « .login », ou un autre script de configuration de l'utilisateur, en fonction de la coque qu'ils utilisent.

+0

Je suis d'accord Jim. Sauf que le cron est exécuté en tant qu'utilisateur que je peux désactiver le script manuellement sans problème. Appelons-le user1 ... Si j'ouvre une session ssh et que je me connecte en tant qu'utilisateur1, puis exécutez /scripts/myscript.sh cela fonctionne très bien mais si j'ajoute le script comme un processus quotidien au cron de user1, il ne termine jamais une course et aucun les erreurs sont générées. Si je supprime "set -e" du début de mon script, il s'exécute correctement à partir de cron et il n'y a pas d'erreur dans stdout ou stderr bien que la sortie du script standard apparaisse. Je suis totalement perplexe sur ce ... – SDGuero

+0

@SDGuero: J'ai développé mon explication de ce qui se passe probablement, avec quelques conseils de dépannage supplémentaires. J'espère que cela t'aides. –

4

Avec set -e, le script s'arrêtera à la première commande qui donne un statut de sortie différent de zéro. Cela ne signifie pas nécessairement que vous verrez un message d'erreur.

Voici un exemple, utilisant la commande false qui ne fait que quitter avec un état d'erreur.

Sans set -e:

$ cat test.sh 
#!/bin/sh 

false 
echo Hello 

$ ./test.sh 
Hello 
$ 

Mais le même script avec set -e sorties sans imprimer quoi que ce soit:

$ cat test2.sh 
#!/bin/sh 

set -e 

false 
echo Hello 

$ ./test2.sh 
$ 

Sur la base de vos observations, il semble que votre script échoue pour une raison quelconque (liée vraisemblablement à l'environnement différent, comme Jim Lewis l'a suggéré) avant qu'il ne génère une sortie.

Pour déboguer, ajoutez set -x au début du script (ainsi que set -e) pour afficher les commandes lors de leur exécution.

Questions connexes