Cron не использует путь пользователя, чей это crontab, и вместо этого имеет свой собственный. Его можно легко изменить, добавив PATH=/foo/bar
в начале crontab, и классический обходной путь - всегда использовать абсолютные пути к командам, запускаемым cron, но где определяется путь PATH по умолчанию для cron?
Я создал crontab со следующим содержимым в моей системе Arch (cronie 1.5.1-1), а также протестировал на Ubuntu 16.04.3 LTS box с такими же результатами:
$ 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). Я полагаю, это в конечном итоге деталь реализации.