web-dev-qa-db-fra.com

crontab PATH et USER

Je suis novice dans la planification de tâches avec cron et crontab. J'essaie de planifier l'exécution d'une tâche comme si je m'étais connecté, que j'avais ouvert un terminal et que je l'avais exécuté moi-même.

Cependant, j'ai planifié une tâche pour m'aider à observer avec quoi $ USER et $ PATH sont exécutés par une tâche planifiée, et voici ce que j'ai trouvé:

$ crontab -l
41 11 * * * echo "USER: $USER" > ~/Desktop/cron_env.log; echo "PATH: $PATH" >> ~/Desktop/cron_env.log
$ cat ~/Desktop/cron_env.log
USER:
PATH: /usr/bin:/bin

Il semble que $ USER n’est pas défini et que $ PATH est très basique et/ou par défaut. Au contraire, c’est ce que je vois lorsque j’ouvre un terminal (connecté) et que je répète ces mêmes informations:

USER: aschirma
PATH: /usr/lib/jvm/Java-6-Sun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/pkg/icetools/bin:/pkg/hwtools/bin:/pkg/netscape/bin:/pkg/gnu/bin

Que dois-je faire pour que mes tâches crontab se déroulent comme je le souhaite?

43
Adam S

Selon "man 5 crontab", vous pouvez définir des variables d'environnement dans votre crontab, en les écrivant avant vos lignes cron.

Il y a aussi un exemple de crontab donc il suffit de le copier/coller:

$ man 5 crontab | grep -C5 PATH | tail 
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

Shell=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow usercommand
17 * * * *  root  cd / && run-parts --report /etc/cron.hourly
25 6 * * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )

Vous pouvez ainsi ajuster votre variable PATH ou toute variable d’environnement à votre guise. Mais cet exemple semble suffisant pour des cas typiques.

73
Julien Palard

Dans * ix, les processus héritent généralement d'un environnement de leur processus parent via fork + exec. Ils ont la possibilité de nettoyer l'environnement, mais généralement pas. Vous pouvez voir l'arbre de processus avec ps axf et les variables d'environnement à l'aide de ps axfe.

en règle générale, cron n'est pas un enfant de quelqu'un de Shell. Par conséquent, son environnement est souvent différent de celui de votre Shell interactif. Il y a de fortes chances pour que cron veuille intentionnellement nettoyer son environnement d'une manière ou d'une autre pour des raisons de cohérence.

J'aime tester mes tâches cron ("foo" pour des raisons de discussion) avec les éléments suivants dans un shell interactif: Env - ./foo Cela effacera en fait plus d’envants que cron, il est plus facile de faire avancer les choses à l’OMI, puisque ce que vous testez est plus similaire. Vous devrez définir les variables dont vous dépendez (telles que $ PATH) ou les remplacer par quelque chose d'autre - EG $ USER devient $ (whoami).

J'aime aussi écrire mes scripts bash pour utiliser "set -eu" et "set -o pipefail". Le -eu dit "exit sur un code de sortie non nul et sur une référence de variable non définie", et le pipefail indique "ne renvoie pas le dernier code de sortie d'un pipeline, mais renvoie le premier code de sortie non nul dans un pipeline" . Dans votre cas, l'ensemble -u pourrait être particulièrement utile.

15
user1277476

N'oubliez pas que crontab est un démon ou un service, il ne ressemble donc pas à un utilisateur connecté. Si vous voulez avoir vos variables d'environnement, vous devrez les définir vous-même. Cependant, la plupart de ces variables sont définies par le shell à partir du chemin/etc/profile, puis dans vos variables personnalisées dans votre répertoire $ HOME. 

Vous pourrez peut-être définir certains d'entre eux en "recherchant" votre/etc/profile comme:

41 11 * * * /home/<me>/cron_env.sh
cron_env.sh contiendra quelque chose comme:
#!/bin/sh
source /etc/profile
/usr/bin/env > /home/<me>/cron_env.log

4
Freddy

Dans notre environnement, nous n'avons généralement pas ce problème car root est le seul cron autorisé et chaque commande est généralement exécutée en tant qu'utilisateur spécifique à l'application VIA et su -c en tant que:

su - myuser -c "/usr/local/scripts/app.sh" 2>&1

puisque l'option "-" est spécifiée, nous obtenons le profil et l'environnement de myuser. Nous avons récemment eu un problème avec une commande qui nécessitait l’autorisation de l’autorité de la racine, nous avons donc lancé la commande sans le su -c. Après de nombreuses recherches, il nous est apparu que le moyen le plus simple d’obtenir l’environnement de root est d’utiliser la même technique pour root que pour toutes les autres applications. Nous avons donc publié: 

su - root -c "/usr/local/scripts/app.sh" 2>&1
3
Alan Kwiatkowski

crontab n'est pas un script bash, vous ne pouvez pas utiliser les variables d'environnement normalement disponibles dans un shell.

Essayez de déplacer tout ce code dans un fichier de script Shebang (un commençant par la ligne "#!/Bin/bash") et exécutez ce script dans la crontab.

Je ne suis pas sûr, mais je pense que PATH (et peut-être EMAIL si vous le définissez) est peut-être le seul auquel vous pouvez accéder à l'intérieur du fichier crontab.

EDIT: Consultez la page de manuel crontab 5 , quelques variables d’environnement sont disponibles, toutes définies par le démon cron.

0
KurzedMetal