views:

808

answers:

4

When running a script with cron, any executable called inside must have the full path. I discovered this trying to run wondershaper, when many errors showed when it tried to call tc. So my question is, what's the proper way to overcome this problem?

Possible solutions:

  • cd to the executable folder and prepare symbolic links to any other called executable there (not sure if it works - low portability)
  • use full paths in the script (it works - low portability across different distros)
  • exporting a path variable with the needed paths inside the script (not sure if it works)

Well, thanks in advance for anyone helping.

+4  A: 

If you're on linux/bsd/mac you can set some environment variables like PATH right in the crontab, and with that you're generally good to go.

If you're on Solaris, well, I pray for you. But, I do have an answer too: I generally source .profile before running anything:

0 0 * * 0 . /home/myuser/.profile && cd /path && ./script

Mind you, my .profile loads .bash_profile and .bashrc. Just be sure whatever file you source has what you need.

kch
+3  A: 

Since cron does not run login, .profile and /etc/profile are not sourced. Therefore PATH may not be set to a value you expect. I would either

  • set and export PATH to an appropriate value
  • use full paths in the script

Your trick with symlinks assumes . is in the PATH and just does not seem nice

Peter van der Heijden
+3  A: 

Declaring variables inside your cron job is more explicit and easier to maintain : all you have to modify is contained in your cron job, and you don't need to transfer multiple files should you move it to another system.

PATH=/usr/bin:/your/fancy/dir
MYAPPROOT=/var/lib/myapp

*/2 * * * * myappinpath
*/3 * * * * $MYAPPROOT/mylocalapp
Luper Rouch
Just a quick comment: Isn't 0-59/2 the same as */2 ?
R. Bemrose
Yes you are right, edited :)
Luper Rouch
+1  A: 

My recomendation:

Set all variables in a external file. I use 'process_name.env' file located in /etc/process_name or similar. Imagine you have a backup script. Then you:

  • Create /etc/backup.env and put all environment variables needed for do the "backup" task.
  • Modify your backup script and add this line after Shebang:

    . /etc/backup.env #There is a dot and a space before full path to backup environment.

IMO this approach is better than declaring variables at CRON definitions because:

  • Easy to maintain. Just edit a file.
  • Easy to switch configuration/centralized configuration:
    • You can have multiple .env for using your script in different situations (for example, consider you have backup locations on your .env, you can pass .env location as an argument and run your cron job daily providing an .env with few locations and weekly with different locations by providing another .env, just a example).
  • You can keep your .env files in a VCS like SVN or Git.
  • Much easy to test your scripts (there is no need to execute it from CRON).

Regards

SourceRebels