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/barna 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/environmentlub /etc/profile.dcron:
$ 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 cronsamo w sobie? Czy nie czyta do tego jakiegoś pliku konfiguracyjnego?
/etc/profiledlatego, że używa tej samej składni ( var=value) co cronsam, więc byłoby to łatwe do zrobienia i, o ile /etc/profilewiem, 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.
zshjako interaktywnej powłoki nie obchodzi /etc/profile(co jest specyficzne bash)
profilepliki są odczytywane tylko przez powłoki logowania. Mogą, ale nie muszą być interaktywne.
stringsz programem może również pomóc w znalezieniu tych zakodowanych wartości.
cronaby patrzeć/etc/profilelub dbać o jakąkolwiek konkretną powłokę. Lepszym pytaniem jest, dlaczego niecronczytaPATHzlogin.defs(w systemie Linux) lublogin.conf(w * BSD). Przypuszczam, że ostatecznie jest to szczegół implementacji.