30 votes

Un bash script peut-il dire s'il est exécuté via cron ?

Je n'ai pas eu beaucoup de chance en cherchant cette question sur Google et j'ai pensé la poster sur SF, mais cela semble être une question de développement. Si ce n'est pas le cas, n'hésitez pas à migrer.

Donc, j'ai un script qui s'exécute via cron tous les matins vers 3 heures. Je lance également les mêmes script manuellement parfois. Le problème est que chaque fois que j'exécute mon script manuellement et qu'il échoue, il m'envoie un e-mail ; même si je peux regarder la sortie et visualiser l'erreur dans la console.

Y a-t-il un moyen pour le bash script de dire qu'il est exécuté par cron (peut-être en utilisant whoami) et de n'envoyer l'e-mail que si c'est le cas ? J'aimerais ne plus recevoir d'e-mails lorsque je fais mes tests...

6voto

Tal Points 272

Je sais que la question est ancienne, mais je viens de rencontrer le même problème. Voici ma solution :

CRON=$(pstree -s $$ | grep -q cron && echo true || echo false)

puis tester avec

if $CRON
then
    echo "Being run by cron"
else
    echo "Not being run by cron"
fi

même idée que celle mentionnée par @eruciform - suit votre PID dans l'arbre de processus en vérifiant le cron.

Remarque : Cette solution ne fonctionne que spécifiquement pour cron, contrairement à certaines des autres solutions, qui fonctionnent chaque fois que le script est exécuté de manière non interactive.

5voto

edoceo Points 96

Ce qui marche pour moi, c'est de vérifier $TERM . Sous cron c'est "dumb" mais sous un shell c'est autre chose. Utilisez l'option set dans votre terminal, puis dans un cron-script et vérifiez-le

if [ "dumb" == "$TERM" ]
then
    echo "cron"
else
    echo "term"
fi

4voto

Grisha Levit Points 4729

J'aimerais proposer une nouvelle réponse à cette question très votée. Cela ne fonctionne que sur les systèmes systemd avec loginctl (par exemple, Ubuntu 14.10+, RHEL/CentOS 7+) mais est capable de donner une réponse beaucoup plus fiable que les solutions présentées précédemment.

service=$(loginctl --property=Service show-session $(</proc/self/sessionid))
if [[ ${service#*=} == 'crond' ]]; then
   echo "running in cron"
fi

Pour résumer : lorsqu'il est utilisé avec systemd, crond (comme sshd et d'autres) crée une nouvelle session lorsqu'il lance un travail pour un utilisateur. Cette session possède un ID qui est unique pendant toute la durée de fonctionnement de la machine. Chaque session possède certaines propriétés, dont le nom du service qui l'a lancée. loginctl peut nous indiquer la valeur de cette propriété, qui sera " crond " si et seulement si la session a en fait été lancée par crond.


Avantages par rapport à l'utilisation de variables d'environnement :

  • Il n'est pas nécessaire de modifier les entrées cron pour ajouter des invocations spéciales ou des variables d'environnement.
  • Aucune possibilité qu'un processus intermédiaire modifie les variables d'environnement pour créer un faux positif ou un faux négatif.

Avantages par rapport au test pour tty :

  • Pas de faux positifs dans les pipelines, les scripts de démarrage, etc.

Avantages par rapport à la vérification de l'arbre des processus :

  • Pas de faux positifs provenant de processus qui ont également crond en leur nom
  • Pas de faux négatifs si le script est désavoué.

2voto

FifthAxiom Points 101

La plupart des commandes utilisées dans les articles précédents ne sont pas disponibles sur tous les systèmes (pstree, loginctl, tty). C'est la seule chose qui a fonctionné pour moi sur un routeur BusyBox/OpenWrt vieux de dix ans que j'utilise actuellement comme serveur DNS de liste noire. Il exécute un script avec une fonctionnalité de mise à jour automatique. Exécuté à partir de crontab, il envoie un email.

[ -z "$TERM" ] || [ "$TERM" = "dumb" ] && echo 'Crontab' || echo 'Interactive'

Dans un shell interactif, l'option $TERM -variable renvoie la valeur vt102 pour moi. J'ai inclus la vérification de "dumb" car @edoceo a mentionné que cela fonctionnait pour lui. Je n'ai pas utilisé '==' car ce n'est pas complètement portable.

0voto

frank42 Points 577

J'ai également aimé l'idée de Tal, mais je vois aussi le risque d'avoir des retours indéfinis. Je me suis retrouvé avec une version légèrement modifiée, qui semble fonctionner très bien à mon avis :

CRON="$( pstree -s $$ | grep -c cron )"

Vous pouvez donc vérifier si $CRON vaut 1 ou 0 à tout moment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X