问题
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.
回答1:
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
回答2:
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.
回答3:
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
回答4:
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
来源:https://stackoverflow.com/questions/819944/proper-way-to-run-a-script-using-cron