web-dev-qa-db-fra.com

Comment simuler l'environnement sur lequel cron exécute un script?

J'ai normalement plusieurs problèmes avec la façon dont cron exécute les scripts, car ils n'ont normalement pas été configurés dans mon environnement. Existe-t-il un moyen d'appeler bash (?) De la même manière que cron pour pouvoir tester les scripts avant de les installer?

224
Jorge Vargas

Ajoutez ceci à votre cron:

30 08 * * * env > ~/cronenv

Après cela, faites ceci:

env - `cat ~/cronenv` /bin/sh

Cela suppose que votre cron exécute/bin/sh, la valeur par défaut, quel que soit le shell par défaut de l'utilisateur.

349
mmccoo

Cron fournit uniquement cet environnement par défaut:

  • HOME répertoire de base de l'utilisateur
  • LOGNAME login de l'utilisateur
  • PATH=/usr/bin:/usr/sbin
  • Shell=/usr/bin/sh

Si vous avez besoin de plus d’informations, vous pouvez créer un script dans lequel vous définissez votre environnement avant la table de planification dans la crontab.

60
gregseth

Couple d'approches:

  1. Exporter cron env et le source:

    Ajouter

    * * * * * env > ~/cronenv
    

    dans votre crontab, laissez-le fonctionner une fois, éteignez-le, puis exécutez

    env - `cat ~/cronenv` /bin/sh
    

    Et vous êtes maintenant dans une session sh qui a l'environnement de cron

  2. Apportez votre environnement à cron

    Vous pouvez passer au-dessus de l'exercice et juste faire un . ~/.profile devant votre tâche cron, par exemple. 

    * * * * * . ~/.profile; your_command
    
  3. Utiliser l'écran

    Les deux solutions ci-dessus échouent toujours car elles fournissent un environnement connecté à une session X en cours d'exécution, avec un accès à dbus etc. Par exemple, sous Ubuntu, nmcli (Network Manager) fonctionnera dans les deux approches ci-dessus, mais échouera toujours dans cron.

    * * * * * /usr/bin/screen -dm
    

    Ajoutez la ligne ci-dessus à cron, laissez-le fonctionner une fois, éteignez-le. Connectez-vous à votre session d'écran (écran -r). Si vous vérifiez que la session d'écran a été créée (avec ps), sachez qu'elles sont parfois en majuscule (par exemple ps | grep SCREEN).

    Maintenant, même nmcli et similaire échoueront.

42
Cookie

Tu peux courir:

env - your_command arguments

Cela exécutera votre_commande avec un environnement vide.

21
dimba

En fonction du shell du compte

Sudo su
env -i /bin/sh

ou

Sudo su
env -i /bin/bash --noprofile --norc

De http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html

13
tcurdt

Six ans plus tard, le problème de l'inadéquation de l'environnement est l'un des problèmes résolus par systemd "timers" en remplacement de cron. Que vous exécutiez le "service" systemd à partir de la CLI ou via cron, il reçoit exactement le même environnement, évitant ainsi le problème de non-concordance de l'environnement.

Le problème le plus courant entraînant l'échec des tâches cron lorsqu'elles sont passées manuellement est la valeur par défaut restrictive $PATH définie par cron, ce qui est le cas sous Ubuntu 16.04:

"/usr/bin:/bin"

En revanche, le $PATH par défaut défini par systemd sur Ubuntu 16.04 est:

"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

Donc, il y a déjà une meilleure chance qu'un minuteur systemd trouve un binaire sans autre problème.

L'inconvénient des minuteries systemd, c'est qu'il leur reste un peu plus de temps pour les configurer. Vous créez d’abord un fichier "service" pour définir ce que vous voulez exécuter, puis un fichier "timer" pour définir la planification de son exécution, puis "activer" le timer pour l’activer. 

12
Mark Stosberg

Créez un travail cron qui exécute env et redirige stdout vers un fichier . Utilisez le fichier à côté de "env -" pour créer le même environnement qu'un travail cron.

10
Jens Carlberg

N'oubliez pas que puisque le parent de cron est init, il exécute des programmes sans terminal de contrôle. Vous pouvez simuler cela avec un outil comme celui-ci:

http://libslack.org/daemon/

3
Randy Proctor

Par défaut, cron exécute ses travaux en utilisant l’idée que votre système a de sh. Il peut s'agir du shell Bourne ou de la variable dash, ash, ksh ou bash (ou une autre) liée à sh (et s'exécutant en mode POSIX).

La meilleure chose à faire est de vous assurer que vos scripts ont ce dont ils ont besoin et de supposer que rien ne leur est fourni. Par conséquent, vous devez utiliser les spécifications complètes du répertoire et définir vous-même les variables d'environnement telles que $PATH.

2
Dennis Williamson

Un autre moyen simple que j'ai trouvé (mais qui peut être sujet à des erreurs, je suis toujours en train de tester) est de générer les fichiers de profil de votre utilisateur avant votre commande.

Éditer un script /etc/cron.d/:

* * * * * user1 comand-that-needs-env-vars

Se transformerait en:

* * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars

Sale, mais le travail a été fait pour moi. Existe-t-il un moyen de simuler un login? Juste une commande que vous pourriez exécuter? bash --login n'a pas fonctionné. Cela semble être la meilleure solution.

EDIT: Cela semble être une solution solide: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/

* * * * * root su --session-command="comand-that-needs-env-vars" user1 -l
1
four43

Answer https://stackoverflow.com/a/2546509/5593430 montre comment obtenir l'environnement cron et l'utiliser pour votre script. Sachez toutefois que l’environnement peut varier en fonction du fichier crontab que vous utilisez. J'ai créé trois entrées cron différentes pour sauvegarder l'environnement via env > log. Ce sont les résultats sur un Amazon Linux 4.4.35-33.55.amzn1.x86_64.

1. Global/etc/crontab avec l'utilisateur root

MAILTO=root
Shell=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
PWD=/
LANG=en_US.UTF-8
SHLVL=1
HOME=/
LOGNAME=root
_=/bin/env

2. Crontab utilisateur de la racine (crontab -e)

Shell=/bin/sh
USER=root
PATH=/usr/bin:/bin
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env

3. Script dans /etc/cron.hourly/

MAILTO=root
Shell=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
_=/bin/env
PWD=/
LANG=en_US.UTF-8
SHLVL=3
HOME=/
LOGNAME=root

Plus important encore, PATH, PWD et HOME diffèrent. Assurez-vous de les définir dans vos scripts cron pour qu'ils reposent sur un environnement stable.

0
Maikel