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
само по себе? Разве он не читает какой-то файл конфигурации для этого?
cron
чтобы смотреть/etc/profile
или заботиться о какой-либо конкретной оболочке. Лучший вопрос - почему неcron
читаетPATH
изlogin.defs
(в Linux) илиlogin.conf
(в * BSD). Я полагаю, это в конечном итоге деталь реализации./etc/profile
потому, что он использует тот же синтаксис (var=value
), что иcron
сам, так что это будет достаточно легко сделать, и/etc/profile
, насколько мне известно, очень широко распространен. Что меня удивило, так это то, что я не мог найти его где-то установленным, так что это выглядело жестко. Как на самом деле, как объяснил Стивен ниже.zsh
качестве своей интерактивной оболочки, плевать на то/etc/profile
(что характерно для нихbash
)profile
файлы в любом случае читаются только оболочками входа в систему. Они могут или не могут быть интерактивными.strings
программы также может помочь найти эти жестко запрограммированные значения.Ответы:
Он жестко запрограммирован в исходном коде (эта ссылка указывает на текущий Debian
cron
- учитывая разнообразиеcron
реализаций, трудно выбрать одну, но другие реализации, вероятно, похожи):cron
не читает пути по умолчанию из файла конфигурации; Я предполагаю, что причина в том, что он поддерживает указание путей, уже используемыхPATH=
в любом cronjob, поэтому нет необходимости указывать значение по умолчанию в другом месте. ( Жестко заданное значение по умолчанию используется, если в записи задания больше ничего не указано .)источник
_PATH_DEFPATH_ROOT
определения, я подтвердил (используя задание cronecho $PATH > /testfile
) после редактирования crontab root с использованиемcrontab -e
в Debian Stretch, который также использует crontab root_PATH_DEFPATH
, то есть «/ usr / bin: / bin», а не_PATH_DEFPATH_ROOT
. Это также подтверждается второй ссылкой исходного кода в этом ответе (в которой_PATH_DEFPATH_ROOT
не используется). Мне не ясно, является ли это осиротевшее определение ошибкой.В добавление к ответу Стивена Китта, есть файл конфигурации, который задает
PATH
для cron в Ubuntu иcron
игнорирует его ,PATH
чтобы использовать жесткоPATH
заданное значение по умолчанию (или s, заданное в самих crontabs). Файл есть/etc/environment
. Примечcron
«сек конфигурации PAM:Это легко проверить. Добавьте переменную
/etc/environment
, скажемfoo=bar
, для запускаenv > /tmp/foo
cronjob и наблюдайте, какfoo=bar
показано в выводе.Это верно в Arch Linux, но в Ubuntu база
PATH
установлена/etc/environment
. Файлы/etc/profile.d
прикрепляются к существующимPATH
, и вы можете добавить их в~/.pam_environment
. У меня есть ошибка, связанная с поведением Арча .К сожалению,
/etc/pam.d/cron
не включает чтение из~/.pam_environment
. Жутко,/etc/pam.d/atd
делает включать этот файл:... но команды, выполняемые через,
at
очевидно, наследуют среду, доступную при созданииat
задания (например,env -i /usr/bin/at ...
кажется, что запускаются задания с очень чистой средой)Поправка
/etc/pam.d/cron
в иметь,user_readenv=1
кажется, не вызывает проблем, и переменные в~/.pam_environment
начали появляться нормально (за исключениемPATH
, конечно).В общем, установка переменных окружения для cron кажется грязным делом. Лучшее место, кажется, в самой спецификации задания, хотя бы потому, что вы не знаете, какие унаследованные переменные среды cron может решить игнорировать (без чтения источника).
источник
at
заданий, если вы выброситеat
задание, вы увидите, что оно явно настраивает среду так, чтобы она соответствовала среде, в которой оно было создано.