it-swarm.com.de

Wo ist Cron's PATH eingestellt?

Cron verwendet nicht den Pfad des Benutzers, dessen Crontab es ist, sondern hat stattdessen einen eigenen. Sie kann leicht geändert werden, indem Sie am Anfang der Crontab PATH=/foo/bar Hinzufügen. Die klassische Problemumgehung besteht darin, immer absolute Pfade zu Befehlen zu verwenden, die von cron ausgeführt werden. Wo ist jedoch der Standardpfad von cron definiert?

Ich habe auf meinem Arch-System (cronie 1.5.1-1) eine Crontab mit den folgenden Inhalten 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 warum? Der systemweite Standardpfad ist in /etc/profile Festgelegt, dies schließt jedoch auch andere Verzeichnisse ein:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

In /etc/environment Oder /etc/profile.d Ist nichts anderes relevant. Die anderen Dateien, von denen ich dachte, dass sie möglicherweise von cron gelesen werden könnten:

$ 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 überraschend, dass in keiner der Dateien in /etc/skel Relevant ist, und es wird auch in keiner /etc/cron* - Datei festgelegt:

$ 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 Standardpfad von cron für Benutzer-Crontabs festgelegt? Ist es in cron selbst fest codiert? Liest es dafür keine Konfigurationsdatei?

36
terdon

Es ist fest codiert in dem Quellcode (dieser Link verweist auf das aktuelle Debian cron - angesichts der Vielzahl von cron-Implementierungen ist es schwierig, eine, aber eine andere auszuwählen Implementierungen sind wahrscheinlich ähnlich):

#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif

cron liest keine Standardpfade aus einer Konfigurationsdatei. Ich stelle mir vor, dass es die Angabe von Pfaden unterstützt, die bereits PATH= In einem Cronjob verwenden, sodass es nicht erforderlich ist, an anderer Stelle einen Standard anzugeben. (Die fest codierte Standardeinstellung wird verwendet wenn in einem Jobeintrag nichts anderes angegeben ist .)

48
Stephen Kitt

Zusätzlich zu Stephen Kitts Antwort gibt es eine Konfigurationsdatei, die PATH für cron unter Ubuntu festlegt, und cron ignoriert dass PATH, um die fest codierte Standardeinstellung zu verwenden (oder PATHs, die in den Crontabs selbst festgelegt sind). Die Datei ist /etc/environment. Hinweis crons PAM-Konfiguration:

$ cat /etc/pam.d/cron
...   
# Read environment variables from pam_env's default files, /etc/environment
# and /etc/security/pam_env.conf.
session       required   pam_env.so

# In addition, read system locale information
session       required   pam_env.so envfile=/etc/default/locale
...

Dies ist leicht zu überprüfen. Fügen Sie /etc/environment Eine Variable hinzu, sagen Sie foo=bar, Führen Sie env > /tmp/foo Als Cronjob aus und beobachten Sie, wie foo=bar In der Ausgabe angezeigt wird.


Aber warum? Der systemweite Standardpfad ist in/etc/profile festgelegt, dies schließt jedoch auch andere Verzeichnisse ein:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

Das stimmt in Arch Linux, aber in Ubuntu ist die Basis PATH in /etc/environment Festgelegt. Dateien in /etc/profile.d Werden an ein vorhandenes PATH angeheftet, und Sie können es in ~/.pam_environment Anhängen. Ich habe ein Fehler über Arch's Verhalten .

Leider enthält /etc/pam.d/cron Kein Lesen von ~/.pam_environment. Seltsamerweise enthält /etc/pam.d/atd diese Datei:

$ cat /etc/pam.d/atd
#
# The PAM configuration file for the at daemon
#

@include common-auth
@include common-account
session    required   pam_loginuid.so
@include common-session-noninteractive
session    required   pam_limits.so
session    required   pam_env.so user_readenv=1

... aber Befehle, die über at ausgeführt werden, erben anscheinend die Umgebung, die beim Erstellen des Jobs at verfügbar ist (zum Beispiel scheint env -i /usr/bin/at ... Jobs mit einer sehr sauberen Umgebung auszuführen).

Das Ändern von /etc/pam.d/cron In user_readenv=1 Scheint keine Probleme zu verursachen, und Variablen in ~/.pam_environment Wurden gut angezeigt (außer natürlich PATH).


Alles in allem scheint das Festlegen von Umgebungsvariablen für cron ein chaotisches Geschäft zu sein. Der beste Platz scheint in der Jobspezifikation selbst zu liegen, schon allein deshalb, weil Sie nicht wissen, welche geerbten Umgebungsvariablen cron möglicherweise ignoriert (ohne die Quelle zu lesen).

9
muru