Cron verwendet nicht den Pfad des Benutzers, dessen crontab es ist, und hat stattdessen einen eigenen. Es kann leicht geändert werden, indem PATH=/foo/bar
am Anfang der crontab hinzugefügt wird. Die klassische Problemumgehung besteht darin, immer absolute Pfade zu Befehlen zu verwenden, die von cron ausgeführt werden. Aber wo ist crons Standard-PATH definiert?
Ich habe eine Crontab mit den folgenden Inhalten auf meinem Arch-System (cronie 1.5.1-1) erstellt und auch auf einer Ubuntu 16.04.3 LTS-Box mit den gleichen Ergebnissen getestet:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Das gedruckt:
$ cat fff
/usr/bin:/bin
Aber wieso? Der systemweite Standardpfad ist in festgelegt /etc/profile
, umfasst jedoch auch andere Verzeichnisse:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
Es gibt nichts anderes Relevantes in /etc/environment
oder /etc/profile.d
in den anderen Dateien, von denen ich dachte, dass sie möglicherweise von cron gelesen werden:
$ 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
Es ist auch nicht /etc/skel
überraschend, dass keine der Dateien in relevant ist oder in einer /etc/cron*
Datei gesetzt wird:
$ 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
Wo wird der Standard-Pfad von cron für Benutzer-Crontabs festgelegt? Ist es in sich cron
selbst fest codiert ? Liest es dafür keine Konfigurationsdatei?
cron
anzuschauen/etc/profile
oder sich um sie zu kümmern . Eine bessere Frage ist, warum nicht von (unter Linux) oder (unter * BSD)cron
gelesen wird . Ich nehme an, es ist letztendlich ein Implementierungsdetail.PATH
login.defs
login.conf
/etc/profile
weil es die gleiche Syntax (var=value
) wie sichcron
selbst verwendet, es wäre also einfach genug und/etc/profile
ist meines Wissens sehr weit verbreitet. Was mich überrascht hat, ist, dass ich es nirgendwo finden konnte und es so aussah, als wäre es hart codiert. Wie es tatsächlich der Fall ist, wie Stephen weiter unten erklärte.zsh
als interaktive Shell verwenden, interessieren sich nicht/etc/profile
(was spezifisch fürbash
)profile
Dateien ohnehin nur von Login-Shells gelesen werden. Diese können interaktiv sein oder auch nicht.strings
kann es auch hilfreich sein, ein Programm zu verwenden, um diese fest codierten Werte zu finden.Antworten:
Es ist im Quellcode fest codiert (dieser Link verweist auf das aktuelle Debian
cron
- angesichts der Vielzahl voncron
Implementierungen ist es schwierig, eine auszuwählen, andere Implementierungen sind jedoch wahrscheinlich ähnlich):cron
liest keine Standardpfade aus einer Konfigurationsdatei; Ich stelle mir vor, dass es die Angabe von Pfaden unterstützt, die bereitsPATH=
in einem Cronjob verwendet werden, sodass es nicht erforderlich ist, an anderer Stelle einen Standardwert anzugeben. (Die fest codierte Standardeinstellung wird verwendet, wenn in einem Auftragseintrag kein anderer Pfad angegeben wurde .)quelle
_PATH_DEFPATH_ROOT
ich trotz des Vorhandenseins des Defines (unter Verwendung eines Cron-Jobs vonecho $PATH > /testfile
) bestätigt habe, nachdem ich die crontab des Roots unter Verwendungcrontab -e
von Debian Stretch bearbeitet habe, die auch die crontab des Roots verwendet_PATH_DEFPATH
, dh "/ usr / bin: / bin", nicht_PATH_DEFPATH_ROOT
. Dies wird auch durch den zweiten Quellcode-Link in dieser Antwort bestätigt (in der_PATH_DEFPATH_ROOT
nicht verwendet wird). Mir ist nicht klar, ob diese verwaiste Definition ein Fehler ist.Stephen Kitts Antwort wird durch eine Konfigurationsdatei ergänzt, die
PATH
unter Ubuntu für cron festgelegt wird und diesecron
ignoriert ,PATH
um die fest codierten Standardeinstellungen (oderPATH
die in den Crontabs selbst festgelegten Werte) zu verwenden. Die Datei ist/etc/environment
. Beachten Siecron
die PAM-Konfiguration:Dies ist leicht überprüfbar. Fügen Sie eine Variable zu
/etc/environment
, sagen wirfoo=bar
, laufenenv > /tmp/foo
als cronjob und zusehen , wiefoo=bar
Shows in der Ausgabe auf.Das stimmt in Arch Linux, aber in Ubuntu ist die Basis
PATH
gesetzt/etc/environment
. Dateien werden/etc/profile.d
an eine vorhandenePATH
angefügt, und Sie können sie in anhängen~/.pam_environment
. Ich habe einen Fehler bezüglich Archs Verhalten .Leider
/etc/pam.d/cron
schließt das Lesen nicht aus~/.pam_environment
. Seltsam,/etc/pam.d/atd
hat diese Datei enthält:... aber Befehle, die über ausgeführt werden
at
, erben anscheinend die Umgebung, die beim Erstellen desat
Jobs verfügbar ist (zum Beispielenv -i /usr/bin/at ...
scheinen Jobs mit einer sehr sauberen Umgebung ausgeführt zu werden).Die Änderung
/etc/pam.d/cron
von haveuser_readenv=1
scheint keine Probleme zu bereiten, und die Variablen in sind~/.pam_environment
in Ordnung (außerPATH
natürlich).Alles in allem scheint das Festlegen von Umgebungsvariablen für cron ein chaotisches Geschäft zu sein. Der beste Platz scheint in der Auftragsspezifikation selbst zu sein, schon allein deshalb, weil Sie nicht wissen, welche vererbten Umgebungsvariablen cron möglicherweise ignoriert (ohne die Quelle zu lesen).
quelle
at
Arbeitsplätze, wenn Sie einen Dumpat
Job Sie werden sehen , es ausdrücklich die Umwelt richtet die Umgebung anzupassen , wenn der Auftrag erstellt wurde.