Cron не використовує шлях того користувача, у якого він є, а натомість має свій власний. Це можна легко змінити, додавши PATH=/foo/bar
на початку crontab, і класичним способом вирішення є завжди використовувати абсолютні шляхи до команд, керованих cron, але де визначено PATH за замовчуванням Cron?
Я створив crontab із наступним вмістом у своїй системі Arch (cronie 1.5.1-1), а також протестував на коробці Ubuntu 16.04.3 LTS з тими ж результатами:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Надруковано:
$ cat fff
/usr/bin:/bin
Але чому? Встановлено стандартний шлях за загальною системою /etc/profile
, але він включає інші каталоги:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
Немає нічого іншого, що стосується /etc/environment
або /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
Немає нічого релевантного в жодному з файлів у /etc/skel
, не дивно, і він не встановлений у жодному /etc/cron*
файлі:
$ 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
Отже, де встановлюється PATH за замовчуванням Cron для користувачів crontabs? Це твердо кодоване cron
саме по собі? Чи не читає якийсь файл конфігурації для цього?
/etc/profile
оскільки він використовує той самий синтаксис ( var=value
), що і cron
сам, тому це зробити досить легко і /etc/profile
, наскільки мені відомо, дуже поширений. Що мене здивувало, це те, що я не міг знайти його встановити ніде, так що це виглядало так, як це було важко закодовано. Як це справді так, як пояснив Стівен нижче.
zsh
свою інтерактивну оболонку, не переймаються /etc/profile
(що характерно для bash
)
profile
файли в будь-якому разі читаються лише оболонками для входу. Вони можуть бути або не бути інтерактивними.
strings
проти програми також може допомогти знайти ці важко кодовані значення.
cron
дивитись/etc/profile
або піклуватися про якусь конкретну оболонку. Краще питання, чому він неcron
читаєPATH
зlogin.defs
(на Linux) абоlogin.conf
(на * BSD). Я вважаю, що це в кінцевому підсумку деталі реалізації.