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?
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./etc/profile
dlatego, że używa tej samej składni (var=value
) cocron
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 specyficznebash
)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.Odpowiedzi:
Jest na stałe zakodowany w kodzie źródłowym (ten link wskazuje na obecny Debian
cron
- biorąc pod uwagę różnorodnośćcron
implementacji, trudno jest wybrać jedną, ale inne implementacje są prawdopodobnie podobne):cron
nie odczytuje domyślnych ścieżek z pliku konfiguracyjnego; Wyobrażam sobie, że istnieje uzasadnienie, że obsługuje ono określanie ścieżek, które już są używanePATH=
w dowolnym kronice, więc nie ma potrzeby określania wartości domyślnej w innym miejscu. (Domyślne zakodowane jest używane, jeśli nic innego nie określa ścieżki we wpisie zadania ).źródło
_PATH_DEFPATH_ROOT
definicji, potwierdziłem (używając zadania cronecho $PATH > /testfile
) po edycji crontab root'a używająccrontab -e
Debian Stretch, którego crontab root również używa_PATH_DEFPATH
, tj. „/ Usr / bin: / bin”, a nie_PATH_DEFPATH_ROOT
. Potwierdza to również drugi link kodu źródłowego w tej odpowiedzi (w którym_PATH_DEFPATH_ROOT
nie jest używany). Nie jest dla mnie jasne, czy to osierocone określenie jest błędem.Dodając do odpowiedzi Stephena Kitta, istnieje plik konfiguracyjny, który ustawia
PATH
dla crona na Ubuntu icron
ignoruje to,PATH
aby użyć zakodowanego domyślnego (lubPATH
s ustawionego w samych plikach crontab). Plik jest/etc/environment
.cron
Konfiguracja PAM notatki :Jest to łatwe do zweryfikowania. Dodaj zmienną do
/etc/environment
, powiedzmyfoo=bar
, uruchomenv > /tmp/foo
jako cronjob i obserwuj, jakfoo=bar
pokazuje wynik.To prawda w Arch Linux, ale w Ubuntu podstawa
PATH
jest ustawiona/etc/environment
. Pliki dołączane do/etc/profile.d
istniejącegoPATH
i można do niego dołączyć~/.pam_environment
. Mam zgłoszony błąd dotyczący zachowania Archa .Niestety
/etc/pam.d/cron
nie obejmuje czytania z~/.pam_environment
. Dziwnie,/etc/pam.d/atd
nie należą do tego pliku:... ale polecenia uruchamiane przez
at
najwyraźniej dziedziczą środowisko dostępne podczas tworzeniaat
zadania (na przykładenv -i /usr/bin/at ...
wydaje się uruchamiać zadania w bardzo czystym środowisku).Zmieniająca
/etc/pam.d/cron
miećuser_readenv=1
wydaje się powodować żadnych problemów, a zmienne~/.pam_environment
zaczęły pojawiać się grzywny (z wyjątkiemPATH
, oczywiście).Podsumowując, ustawianie zmiennych środowiskowych dla crona wydaje się być bałaganem. Najlepszym miejscem wydaje się być sama specyfikacja zadania, choćby dlatego, że nie wiesz, które odziedziczone zmienne środowiskowe cron może zdecydować zignorować (bez czytania źródła).
źródło
at
zadania, jeśli zrzuciszat
zadanie, zobaczysz, że jawnie ustawia środowisko tak, aby pasowało do środowiska, w którym zostało utworzone zadanie.