Cron doesn't use the path of the user whose crontab it is and, instead, has its own. It can easily be changed by adding PATH=/foo/bar
at the beginning of the crontab, and the classic workaround is to always use absolute paths to commands run by cron, but where is cron's default PATH defined?
I created a crontab with the following contents on my Arch system (cronie 1.5.1-1) and also tested on an Ubuntu 16.04.3 LTS box with the same results:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
That printed:
$ cat fff
/usr/bin:/bin
But why? The default system-wide path is set in /etc/profile
, but that includes other directories:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
There is nothing else relevant in /etc/environment
or /etc/profile.d
, the other files I thought might possibly be read by 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
There is also nothing relevant in any of the files in /etc/skel
, unsurprisingly, nor is it being set in any /etc/cron*
file:
$ 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
So, where is cron's default PATH for user crontabs being set? Is it hardcoded in cron
itself? Doesn't it read some sort of configuration file for this?
Best Answer
It’s hard-coded in the source code (that link points to the current Debian
cron
— given the variety ofcron
implementations, it’s hard to choose one, but other implementations are likely similar):cron
doesn’t read default paths from a configuration file; I imagine the reasoning there is that it supports specifying paths already usingPATH=
in any cronjob, so there’s no need to be able to specify a default elsewhere. (The hard-coded default is used if nothing else specified a path in a job entry.)