l'exécution de crontab n'a pas les mêmes variables d'environnement que l'utilisateur exécutant

20

J'ai exécuté mon travail crontab en 0 2 */1 * * /aScript >aLog.log 2>&1tant qu'utilisateur 'root', et cependant j'ai trouvé que l'env est différent de l'env de l'utilisateur 'root', et que j'ai donc un comportement d'exécution différent de mes scripts.

Un correctif tentait de placer les commandes d'exportation dans les fichiers rc.d, mais il ne s'est toujours pas affiché! Je finis par placer des commandes d'exportation dans aScript lui-même.

Ma question est qu'il existe une meilleure façon d'aborder ce problème? et pourquoi env manque même s'il provient du même utilisateur "root"? (Je modifie crontab en exécutant 'crontab -e' depuis la racine)

Bambou
la source
8
Cron fonctionne toujours avec un environnement principalement vide. HOME, LOGNAME et SHELL sont définis; et un CHEMIN très limité. Si vous ne souhaitez pas définir toutes les variables vous-même, vous pourrez peut-être accéder à sourcevotre profil (bash).
cyberx86
2
@ cyberx86: Pourquoi ne pas écrire cela comme réponse et obtenir un représentant?
user9517 prend en charge GoFundMonica
2
@Iain: le représentant est toujours le bienvenu - mais parfois, il semble qu'une réponse sur une seule ligne ne gagne pas vraiment le représentant. J'accepte pleinement qu'une réponse succincte ait sa place, mais j'ai utilisé (peut-être à tort) des commentaires comme une `` solution de facilité '' lorsque je voulais apporter une aide, mais pas rédiger une explication complète et détaillée (il était 1h du matin. ..). Je vais cependant suivre vos conseils et développer un peu celui-ci et l'ajouter comme réponse.
cyberx86
@ cyberx86: Mieux vaut avoir un liner correct que incorrect ou rien.
user9517 prend en charge GoFundMonica

Réponses:

31

Cron fonctionne toujours avec un environnement principalement vide. HOME, LOGNAME et SHELL sont définis; et un CHEMIN très limité. Il est donc conseillé d'utiliser des chemins d'accès complets aux exécutables et d'exporter toutes les variables dont vous avez besoin dans votre script lors de l'utilisation de cron.

Il existe plusieurs approches que vous pouvez utiliser pour définir vos variables d'environnement dans cron, mais elles reviennent toutes à les définir dans votre script.

Approche 1:

Définissez manuellement chaque variable dont vous avez besoin dans votre script.

Approche 2:

Sourcez votre profil:

. $HOME/.bash_profile(ou . $HOME/.profile)

(Vous constaterez généralement que le fichier ci-dessus source d'autres fichiers (par exemple ~ / .bashrc -> / etc / bashrc -> /etc/profile.d/*) - sinon, vous pouvez également les source.)

Approche 3:

Enregistrez vos variables d'environnement dans un fichier (exécutez en tant qu'utilisateur souhaité):

env > /path/to/my_env.sh

Importez ensuite via votre script cron:

env - `cat /path/to/my_env.sh` /bin/sh

Approche 4:

Dans certains cas, vous pouvez définir des variables cron globales dans /etc/default/cron. Il y a cependant un élément de risque, car ceux-ci seront définis pour toutes les tâches cron.

cyberx86
la source
L'approche 2 est la meilleure pour les serveurs où vous avez des choses sensibles qui ne devraient pas frapper le disque dans les vars env - mots de passe, clés api, etc. J'ai fait des merveilles, alors merci.
ap
L'approche 4 a fonctionné pour moi dans un environnement docker où le moteur docker définit les vars env. Pour que cela fonctionne, j'ai dû enregistrer mon env dans le point d'entrée docker. La solution complète est ici: github.com/rayyanqcri/swarm-scheduler
hammady
Pourriez-vous m'expliquer l'approche 3? Lorsque j'essaie de l'importer, je reçoisbash: SHELL=/bin/bash: No such file
KuboMD
1

Cron crée son OWN shell avec l'utilisation spécifiée à travers laquelle il s'exécutera.

Donc, si vous souhaitez conserver la même variable de votre utilisateur, essayez de l'exécuter avec votre propre utilisateur, au lieu de root ou de tout autre utilisateur.

Ou

La meilleure façon est d'exporter ces variables dans votre propre script.

Farhan
la source
1

Dans RedHat CentOS, vous pouvez définir /etc/rc.d/init.d/functions par défaut PATH pour définir de manière permanente. /etc/rc.d/crond appelle des fonctions au démarrage.

user215450
la source
0

J'ai eu un problème similaire sur mon AWS. Compris comme ça

which python3

m'a donné l' /usr/bin/local/python3emplacement

puis

. $HOME/.profile; /usr/local/bin/python3 /home/ubuntu/your_script.py
Al Po
la source