Cron n'utilise pas le chemin de l'utilisateur dont elle est la crontab et a le sien. Elle peut facilement être modifiée en ajoutant PATH=/foo/bar
au début de la crontab, et la solution classique consiste à toujours utiliser des chemins absolus pour les commandes exécutées par cron, mais où est défini le PATH par défaut de cron?
J'ai créé une crontab avec le contenu suivant sur mon système Arch (cronie 1.5.1-1) et également testé sur une boîte Ubuntu 16.04.3 LTS avec les mêmes résultats:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
C'est imprimé:
$ cat fff
/usr/bin:/bin
Mais pourquoi? Le chemin par défaut du système est défini dans /etc/profile
, mais cela inclut d'autres répertoires:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
Il n'y a rien d'autre de pertinent dans /etc/environment
ni /etc/profile.d
les autres fichiers que je pensais susceptibles d'être lus par cron:
$ grep PATH= /etc/profile.d/* /etc/environment
/etc/profile.d/jre.sh:export PATH=${PATH}:/usr/lib/jvm/default/bin
/etc/profile.d/mozilla-common.sh:export MOZ_PLUGIN_PATH="/usr/lib/mozilla/plugins"
/etc/profile.d/perlbin.sh:[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl
Il n’ya rien de /etc/skel
surprenant non plus dans les /etc/cron*
fichiers qui se trouvent dans aucun fichier:
$ grep PATH /etc/cron* /etc/cron*/*
grep: /etc/cron.d: Is a directory
grep: /etc/cron.daily: Is a directory
grep: /etc/cron.hourly: Is a directory
grep: /etc/cron.monthly: Is a directory
grep: /etc/cron.weekly: Is a directory
/etc/cron.d/0hourly:PATH=/sbin:/bin:/usr/sbin:/usr/bin
Alors, où est le PATH par défaut de cron pour les crontabs utilisateur en cours de définition? Est-ce qu'il est codé en dur cron
? Ne lit-il pas une sorte de fichier de configuration pour cela?
cron
de regarder/etc/profile
ou de s'intéresser à une coquille particulière. Une meilleure question est pourquoi ne pascron
lire àPATH
partir delogin.defs
(sous Linux) oulogin.conf
(* sur BSD). Je suppose que c'est finalement un détail de mise en œuvre./etc/profile
car il utilise la même syntaxe (var=value
) quecron
lui-même, il serait donc assez facile à faire et/etc/profile
est, à ma connaissance, très répandu. Ce qui m'a surpris, c'est que je ne pouvais pas le trouver installé nulle part, donc il semblait que c'était codé en dur. Comme c'est en effet le cas, comme l'a expliqué Stephen ci-dessous.zsh
de shell interactif ne s’intéressent pas à la question/etc/profile
(ce qui est propre àbash
)profile
fichiers ne sont lus que par des shells de connexion. Ceux-ci peuvent ou non être interactifs.strings
contre un programme peut aussi aider à trouver ces valeurs codées en dur.Réponses:
C'est codé en dur dans le code source (ce lien pointe vers l'actuelle Debian
cron
- étant donné la diversité descron
implémentations, il est difficile d'en choisir une, mais d'autres implémentations sont probablement similaires):cron
ne lit pas les chemins par défaut à partir d'un fichier de configuration; J'imagine que la raison en est qu'il prend en charge la spécification de chemins déjà utilisésPATH=
dans n'importe quel travail cron, il n'est donc pas nécessaire de pouvoir spécifier un paramètre par défaut ailleurs. (La valeur par défaut codée en dur est utilisée si rien d'autre n'a spécifié un chemin d'accès dans une entrée de travail .)la source
_PATH_DEFPATH_ROOT
définition, j’ai confirmé (en utilisant une tâche cron deecho $PATH > /testfile
) après avoir modifié la crontab de la racine en utilisantcrontab -e
sur Debian Stretch que la crontab de cette racine utilise également_PATH_DEFPATH
, c’est-à-dire "/ usr / bin: / bin"_PATH_DEFPATH_ROOT
. Ceci est également confirmé par le deuxième lien de code source dans cette réponse (dans lequel_PATH_DEFPATH_ROOT
n'est pas utilisé). Il n'est pas clair pour moi si cette définition orpheline est un bogue.Ajout à la réponse de Stephen Kitt, il y a un fichier de configuration qui définit
PATH
Cron sur Ubuntu, etcron
ignore quePATH
d'utiliser la valeur par défaut codées en dur (ouPATH
s définies dans les crontabs eux - mêmes). Le fichier est/etc/environment
. Remarque surcron
la configuration de PAM:Ceci est facilement vérifiable. Ajoutez une variable pour
/etc/environment
, par exemplefoo=bar
, exécuter enenv > /tmp/foo
tant que travail cron et regarder comme indiquéfoo=bar
dans la sortie.C’est vrai dans Arch Linux, mais dans Ubuntu, la base
PATH
est définie/etc/environment
. Les fichiers sont/etc/profile.d
ajoutés à un fichier existantPATH
et vous pouvez les ajouter à~/.pam_environment
. J'ai un bug sur le comportement d'Arch .Malheureusement,
/etc/pam.d/cron
ne comprend pas la lecture de~/.pam_environment
. Bizarrement,/etc/pam.d/atd
ne comprend ce fichier:... mais les commandes exécutées via
at
héritent apparemment de l'environnement disponible lors de la création duat
travail (par exemple,env -i /usr/bin/at ...
semble exécuter des travaux avec un environnement très propre).Modifier
/etc/pam.d/cron
pour avoiruser_readenv=1
semble ne poser aucun problème, et les variables~/.pam_environment
commencent à apparaître très bien (sauf pourPATH
, bien sûr).Tout compte fait, définir des variables d'environnement pour cron semble être une entreprise complexe. Le meilleur endroit semble être dans la spécification du travail lui-même, ne serait-ce que parce que vous ne savez pas quelles variables d'environnement héritées cron pourrait décider d'ignorer (sans lire le code source).
la source
at
travaux, si vousat
videz un travail, vous verrez qu'il configure explicitement l'environnement pour qu'il corresponde à l'environnement lors de la création du travail.