Cron不会使用crontab而是拥有自己的crontab的用户的路径。可以通过PATH=/foo/bar
在crontab的开头添加内容来轻松更改它,经典的解决方法是始终使用绝对路径访问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
那么,在哪里为用户crontabs设置了cron的默认PATH?它cron
本身是硬编码的吗?它不是为此读取某种配置文件吗?
/etc/profile
它,因为它使用与自身相同的语法(var=value
)cron
,所以这样做很容易/etc/profile
,据我所知,它非常普及。令我惊讶的是,我找不到它可以放置在任何地方,因此看起来好像是硬编码的。的确如此,正如斯蒂芬在下面解释的那样。
zsh
它们用作交互式外壳并不关心/etc/profile
(特定于bash
)
profile
文件只能由登录外壳程序读取。这些可能是互动的,也可能不是互动的。
strings
针对程序运行也可以帮助找到这些硬编码的值。
cron
去看/etc/profile
或关心任何特定的外壳。一个更好的问题是为什么不从(在Linux上)或(在* BSD上)cron
读取。我想这最终是实现细节。PATH
login.defs
login.conf