Cron nie korzysta ze ścieżki użytkownika, którego crontab jest, a zamiast tego ma swoją własną. Można to łatwo zmienić, dodając PATH=/foo/bar
na początku crontab, a klasycznym obejściem jest zawsze używanie ścieżek bezwzględnych do poleceń uruchamianych przez crona, ale gdzie jest zdefiniowana domyślna ŚCIEŻKA crona?
Stworzyłem crontab z następującą zawartością w moim systemie Arch (cronie 1.5.1-1), a także testowałem na Ubuntu 16.04.3 LTS z tymi samymi wynikami:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Które wydrukowano:
$ cat fff
/usr/bin:/bin
Ale dlaczego? Domyślna ścieżka systemowa jest ustawiona /etc/profile
, ale zawiera inne katalogi:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
W innych plikach nie ma nic istotnego /etc/environment
lub /etc/profile.d
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
Tam też nic nie istotne w dowolne pliki /etc/skel
, nie dziwi, ani nie jest to zestaw będąc w dowolnym /etc/cron*
pliku:
$ 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
Więc gdzie jest ustawiona domyślna ŚCIEŻKA crona dla crontab użytkownika? Czy to jest zakodowane cron
samo w sobie? Czy nie czyta do tego jakiegoś pliku konfiguracyjnego?
/etc/profile
dlatego, że używa tej samej składni ( var=value
) co cron
sam, więc byłoby to łatwe do zrobienia i, o ile /etc/profile
wiem, jest bardzo rozpowszechnione. Zaskoczyło mnie to, że nie mogłem go nigdzie ustawić, więc wyglądało na to, że jest mocno zakodowany. Tak jak w rzeczywistości, jak wyjaśnił Stephen poniżej.
zsh
jako interaktywnej powłoki nie obchodzi /etc/profile
(co jest specyficzne bash
)
profile
pliki są odczytywane tylko przez powłoki logowania. Mogą, ale nie muszą być interaktywne.
strings
z programem może również pomóc w znalezieniu tych zakodowanych wartości.
cron
aby patrzeć/etc/profile
lub dbać o jakąkolwiek konkretną powłokę. Lepszym pytaniem jest, dlaczego niecron
czytaPATH
zlogin.defs
(w systemie Linux) lublogin.conf
(w * BSD). Przypuszczam, że ostatecznie jest to szczegół implementacji.