2010-03-09 4 views
-1

J'ai un script qui appelle à un tas de commandes, dont certaines sont bruyantes à stdout, d'autres à stderr, d'autres aux deux. J'ai l'intention que le script soit exécuté par cron, donc je ne veux pas qu'il soit bruyant et m'envoyer un mail tous les jours - seulement dans des conditions d'erreur. Alors je fais:Bash + cron: Rediriger, et restaurer, stdout et stderr produit l'autorisation refusée

be_quiet() { 
    # save stderr in FD 3 
    exec 3>&2 

    exec &> /dev/null 
} 

die() { 
    # restore stderr 
    exec 2>&3 

    echo $* > /dev/stderr 
    exit 1 
} 

Puis, à savoir

be_quiet 
mkdir -p $CLIENT_ROOT || die "Could not create client root." 
cd $CLIENT_ROOT || die "Could not cd to client root." 

Le but étant que je reçois des messages spécifiques et significatifs à moi, s'il y a une erreur, et rien autrement. Mais ce que je vois maintenant est juste

line 48: /dev/stderr: Permission denied 

Lorsque exécuté à partir de la ligne de commande, cela fonctionne. Lorsqu'il est exécuté via cron, il donne le message d'autorisation refusée. Je ne sais pas pourquoi.

+0

Est-ce que 'exec 3> & 2' est correct? stderr est généralement '2'. –

+0

Cela signifie que vous n'avez pas d'autorisation en écriture sur/dev/stderr. Vos tâches cron s'exécutent-elles sous le même identifiant d'utilisateur et de groupe que votre shell interactif? Passez-vous automatiquement à un groupe spécifique dans votre fichier .profile, peut-être tty? –

+0

> exec 3> & 2 est-il correct? Oui. Comme je l'ai dit, cela fonctionne de manière interactive. Essayez ce script: echo "Visible 1" >>/dev/stderr exec 3> & 2 exec &>/dev/null echo "Invisible" >>/dev/stderr exec 2> & 3 écho "Visible 2" >>/dev/stderr Encore une fois, cela fonctionne interactivement mais échoue via cron. > Vos tâches cron s'exécutent-elles sous le même identifiant d'utilisateur et de groupe que votre shell interactif? Oui. > Passez-vous automatiquement à un groupe spécifique dans votre .profile? n ° – arantius

Répondre

2

Au lieu de

exec 2>&3 

do

exec 3>&- 
+0

Qu'est-ce que cela fait? Pouvez-vous inclure l'exemple complet avec stdout/stderr? –

0

Pourquoi ne pas simplement stdout dans le redirigent cronjob/dev/null? Ne pas utiliser la fonction be_quiet et le changement meurent à:

die() { 
    echo "$*" >&2 
} 

Ensuite, dans votre cronjob:

* * * * * /path/to/script.sh >/dev/null 

Vous ne devriez obtenir le courrier de Cron lorsque les sorties de votre script quelque chose en utilisant la fonction de la filière.

+0

> Pourquoi ne pas simplement rediriger stdout ... Parce que certaines des commandes que j'exécute sont bruyantes à stdout, et d'autres à stderr (et certaines à la fois). Comme je l'ai dit dans la toute première phrase de ma question. – arantius

+0

Je dois avoir mal compris, vous avez dit que vous voulez seulement être envoyé pour des conditions d'erreur, donc j'ai supposé que vous ne vouliez rien voir de stdout et tout de stderr. –

Questions connexes