Cron

cron 的 PATH 設置在哪裡?

  • January 30, 2020

Cron 不使用 crontab 所在使用者的路徑,而是擁有自己的路徑。它可以通過在 crontab 的開頭添加來輕鬆更改,PATH=/foo/bar經典的解決方法是始終使用 cron 執行的命令的絕對路徑,但是 cron 的預設 PATH 定義在哪裡?

我在我的 Arch 系統(cronie 1.5.1-1)上創建了一個包含以下內容的 crontab,並在 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

那麼,使用者 crontab 的 cron 的預設 PATH 設置在哪裡?它本身是硬編碼的cron嗎?它不會為此讀取某種配置文件嗎?

它在原始碼中被硬編碼(該連結指向目前的 Debian——cron鑑於cron實現的多樣性,很難選擇一個,但其他實現可能相似):

#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif

cron不從配置文件中讀取預設路徑;我想其中的原因是它支持指定已PATH=在任何 cronjob 中使用的路徑,因此無需在其他地方指定預設值。(如果在作業條目中沒有指定路徑,則使用硬編碼預設值。)

引用自:https://unix.stackexchange.com/questions/401621