1 votes

Comment rediriger la sortie et sortir en cas d'échec de la commande ?

C'est ainsi que je consigne à la fois stdout et stderr dans mes scripts (généralement des cronjobs) :

#!/bin/bash
mylog() {
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] $1"
}
(
mylog 'start'

some-command || mylog 'error' && exit 1

mylog 'end'
) >> /var/log/my-log.log 2>&1

Dans certains scripts, j'utilise return au lieu de exit et cela fonctionne bien, mais maintenant il dit que je ne peux pas utiliser return à moins d'inclure le scripts avec src ou de l'utiliser dans une fonction. Je l'ai donc changé en exit, mais le problème est que cela n'enregistre rien, il semble que cela arrête la >> redirection de sortie. Un autre problème est que je ne pourrai pas l'inclure plus tard avec src, parce que je veux seulement arrêter ce scripts, pas tout.

J'utilise la redirection de sortie parce que je veux tout enregistrer, même si aucune erreur ne s'est produite. Et parfois, les commandes ne renvoient même pas les codes de sortie appropriés, donc je ne peux pas faire confiance à cela.

Alors comment puis-je "retourner" en cas d'erreur ? Je connais 'set -e', mais je préfère avoir plus de contrôle sur le moment où il faut arrêter le script.

Des idées ?

1voto

Scott Points 20468

Je ne peux pas expliquer le comportement que vous rencontrez, mais voici une solution possible :

#!/bin/bash
mylog() {
    echo "\[$(date '+%Y-%m-%d %H:%M:%S')\] $1"
}

mymain() {
    (
        mylog 'start'

        some-command  ||  mylog 'error'  &&  return 1

        mylog 'end'
    ) >> /var/log/my-log.log 2>&1
}

mymain

Alternativement, supprimez la redirection du mymain et la placer dans le fichier mymain appel de fonction :

mymain >> /var/log/my-log.log 2>&1

(Vous devriez être en mesure de supprimer les parenthèses de l'adresse de l'utilisateur. mymain définition de la fonction à l'époque, également).  Alternativement, puisque vous voulez que IO soit redirigé pour la fonction tout le site script, vous pouvez séparer la redirection des déclarations d'action :

exec >> /var/log/my-log.log
exec 2>&1
mymain

Puisque je ne comprends pas pourquoi votre approche échoue, je ne peux pas expliquer pourquoi l'une des solutions ci-dessus a plus de chances de fonctionner comme souhaité.  Cependant, ce sont des façons légèrement différentes de faire la même chose, et cela pourrait être juste suffisant.  Au fait, j'ai modifié `date …` a $(date …) juste pour des raisons générales ; Je ne pense pas que cela ait quelque chose à voir avec votre problème.

0voto

mdpc Points 4340

Que diriez-vous d'utiliser le screen sous linux ? Cela devrait faire l'affaire, à moins que vous n'ayez à cœur de programmer une solution vous-même.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X