added HOME=/home/felipe but cron does not recognise

I am having a problem with cron finding executable files in my ~/bin directory. I am aware that PATH is not set, and must be set explicitly (or absolute path name used.) To avoid the use of absolute paths, I included a PATH declaration in my crontab. But I am getting mail saying “could not find rsync-suse-amd.sh”

felipe@suse-amd:~> crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (crontab/crontab installed on Fri Mar 27 03:28:52 2009)
# (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $)
#
# i have also tried commenting the line below
#
HOME=/home/felipe
PATH=$HOME/bin:/usr/bin:/bin
1 1 1-31/2 * * rsync-suse-amd.sh
#1-59/2 * * * * date
felipe@suse-amd:~>

Man 5 crontab

Several environment variables are set up automatically by the cron(8)
daemon. SHELL is set to /bin/sh, and LOGNAME and HOME are set from the
/etc/passwd line of the crontab’s owner. HOME and SHELL may be over-
ridden by settings in the crontab; LOGNAME may not.

Why doesn’t cron use $HOME/bin to search for “rsync-suse-amd.sh”

felipe@suse-amd:~> ll ~/bin/rsync-suse-amd.sh
-rwxr--r-- 1 felipe users 280 2009-03-28 18:56 /home/felipe/bin/rsync-suse-amd.sh
felipe@suse-amd:~>

This is one of those slightly obscure areas of Linux/Unix. You see, what happens is that crontab doesn’t support the full syntax of a shell environment assignment. Create a crontab like this, and you will see why:

PATH=/home/felipe/bin:$PATH
* * * * * /usr/bin/env

When you get the email you will see that env tells you that PATH=/home/felipe/bin:$PATH literally. In other words, crontab only assigns, it doesn’t substitute any $ variables. So it’s slightly deficient. But it never claimed full compatibility on the man page.

However all is not lost. You can use the normal shell syntax for environment variable assignment ahead of the command:

1 1 1-31/2 * * PATH=$HOME/bin:/usr/bin:/bin rsync-suse-amd.sh

Not many people realise you can do this in the shell:

PATH=blahblah command

(note, only whitespace after the assignment and definitely no semicolon) and not have to do, in bash:


export PATH=blahblah
command

or more tedious, for classic sh:

PATH=blahblah
export PATH
command

when you only want to affect one command. And that goes for any variable, not just PATH.

Thanks. I wasn’t aware of those ‘deficiencies’ (now I am …).

What about ${HOME} or “$HOME” will those work?

I don’t see a need to add PATH line on the cron command line. I might as well just write the absolute path! (i don’t want to do that).

No, no handling of $ at all is done.

Changing PATH may not be useful for that command itself since you can write an absolute path for that, but it may be for commands run inside that script.

I’ll just do:
PATH=/home/felipe/bin:/bin:/usr/bin

Thanks for clarifying! I had a hard time with this one :wink:

Sure, that’ll work too.

I wouldn’t want to set PATH for all jobs in the crontab though. That’s why I prefer to use per-command assignments.

Wouldn’t having a global PATH make it a lot easier to maintain, change, use, …?

Well it means you are setting something that could deviate from the default. The advantage of the PATH=…$PATH thingy, what you quite reasonably wanted to do, was that it prepended to PATH so if openSUSE decided that say /opt/something/bin would from now on be part of the standard PATH, your cron jobs would pick that up as a matter of course. But since that isn’t possible with crontab syntax, I prefer to highlight the jobs that require my specific directories by prepending to the PATH just for those jobs. It’s just the way I prefer to do things.