如何让CRON调用正确的path
我试图让cron调用正确的PATH。 当我从shell运行Python脚本时,脚本运行良好,因为它使用了在bashrc中设置的PATH,但是当我使用cron时,所有的PATH都不能在bashrc中使用。 有没有一个文件,我可以inputpath进入cron的bashrc或从bashrc调用path的方式?
对不起,我不认为我正确的措辞,我可以得到正确的脚本运行(意味着在crontab脚本的path不是这里的问题),只是当这个脚本运行我运行一个构build,这使用path在.bashrc
设置。 当我在login时运行脚本时,会拉入.bashrc
PATH。由于cron不能在shell中运行,因此不会在.bashrc
拉动。 有没有办法拉这个,而不必写一个bash脚本包装?
我用/etc/crontab
。 我使用vi
并input到我需要的path中,并以root身份运行。 正常的crontab会覆盖你设置的path。 一个很好的教程,如何做到这一点是: http : //unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5 。
系统范围的cron文件如下所示:
This has the username field, as used by /etc/crontab. # /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file. # This file also has a username field, that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # mh dom mon dow user command 42 6 * * * root run-parts --report /etc/cron.daily 47 6 * * 7 root run-parts --report /etc/cron.weekly 52 6 1 * * root run-parts --report /etc/cron.monthly 01 01 * * 1-5 root python /path/to/file.py
很可能,cron运行在一个非常稀疏的环境中。 通过附加一个虚拟作业来检查cron正在使用的环境variables,这个作业将env
转储到文件中,如下所示:
* * * * * env > env_dump.txt
将它与普通shell会话中的env
输出进行比较。
你可以在crontab的顶部定义你自己的环境variables到本地的crontab。
以下是将$PATH
预先添加到当前crontab的快速修复:
# echo PATH=$PATH > tmp.cron # echo >> tmp.cron # crontab -l >> tmp.cron # crontab tmp.cron
得到的crontab看起来与chrissygormley的答案类似,在crontab规则之前定义了PATH。
你应该把完整的path在你的crontab
。 这是最安全的select。
如果你不想这样做,你可以在程序中放置一个包装脚本,并在那里设置PATH。
例如
01 01 * * * command
变为:
01 01 * * * /full/path/to/command
另外,从cron
调用的任何东西都应该对它运行的程序非常小心,并可能为PATH
variables设置自己的select。
编辑:
如果你不知道你的命令是从哪里执行的which <command>
那么它会告诉你path。
EDIT2:
所以一旦你的程序运行了,它应该做的第一件事就是将PATH
和任何其他必需的variables(例如LD_LIBRARY_PATH
)设置为脚本运行所需的值。
基本上,不要考虑如何修改cron环境,使其更适合你的程序/脚本 – 让你的脚本处理它的环境,通过设置适当的启动时间。
让你的variables为你工作,这将允许访问吨
在/etc/profile.d/*.sh中定义你的PATH
全系统的环境variables
无论何时inputbashloginshell(例如,从控制台或通过sshlogin时),以及在桌面会话加载时由DisplayManager执行/etc/profile.d目录中扩展名为.sh的文件。
你可以创build文件/etc/profile.d/myenvvars.sh并设置如下variables:
export JAVA_HOME=/usr/lib/jvm/jdk1.7.0 export PATH=$PATH:$JAVA_HOME/bin
用login选项执行crontab!
CRONTAB运行脚本或命令与环境variables
0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c 'php -f ./download.php' 0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c download.sh
在我的crontab中的命令行之前设置PATH为我工作:
* * * * * PATH=$PATH:/usr/local/bin /path/to/some/thing
问题
当你从控制台运行脚本时,你的脚本工作,但在cron中失败。
原因
你的crontab没有正确的pathvariables(可能还有shell)
解
添加你的当前shell和path的crontab
脚本为你做
#!/bin/bash # # Date: August 22, 2013 # Author: Steve Stonebraker # File: add_current_shell_and_path_to_crontab.sh # Description: Add current user's shell and path to crontab # Source: http://brakertech.com/add-current-path-to-crontab # Github: hhttps://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh # function that is called when the script exits (cleans up our tmp.cron file) function finish { [ -e "tmp.cron" ] && rm tmp.cron; } #whenver the script exits call the function "finish" trap finish EXIT ######################################## # pretty printing functions function print_status { echo -e "\x1B[01;34m[*]\x1B[0m $1"; } function print_good { echo -e "\x1B[01;32m[*]\x1B[0m $1"; } function print_error { echo -e "\x1B[01;31m[*]\x1B[0m $1"; } function print_notification { echo -e "\x1B[01;33m[*]\x1B[0m $1"; } function printline { hr=------------------------------------------------------------------------------------------------------------------------------- printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}" } #################################### # print message and exit program function die { print_error "$1"; exit 1; } #################################### # user must have at least one job in their crontab function require_gt1_user_crontab_job { crontab -l &> /dev/null [ $? -ne 0 ] && die "Script requires you have at least one user crontab job!" } #################################### # Add current shell and path to user's crontab function add_shell_path_to_crontab { #print info about what's being added print_notification "Current SHELL: ${SHELL}" print_notification "Current PATH: ${PATH}" #Add current shell and path to crontab print_status "Adding current SHELL and PATH to crontab \nold crontab:" printline; crontab -l; printline #keep old comments but start new crontab file crontab -l | grep "^#" > tmp.cron #Add our current shell and path to the new crontab file echo -e "SHELL=${SHELL}\nPATH=${PATH}\n" >> tmp.cron #Add old crontab entries but ignore comments or any shell or path statements crontab -l | grep -v "^#" | grep -v "SHELL" | grep -v "PATH" >> tmp.cron #load up the new crontab we just created crontab tmp.cron #Display new crontab print_good "New crontab:" printline; crontab -l; printline } require_gt1_user_crontab_job add_shell_path_to_crontab
资源
示例输出
用正确的值添加一个PATH定义到用户crontab将有助于…我已经填写我的只是:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
让我所有的脚本都能正常工作就足够了……如果需要,可以在其中包含任何自定义path。
cron作业的默认环境非常稀疏,可能与您开发Python脚本的环境有很大的差异。对于可能在cron中运行的脚本,应该明确设置您所依赖的任何环境。 在cron文件本身中,包含python可执行文件的完整path和python脚本。
在我的AIX上,cron从/ etc / environment中选取环境variables,忽略.profile中设置的内容。
编辑:我也检查了几个不同年龄的Linux机器,这些文件似乎也有这个文件,所以这可能不是特定于AIX的。
我使用joemaller的cronbuild议检查了这一点,并在/ etc / environment中编辑PATHvariables之前和之后检查输出。
我知道这已经被回答了,但是我认为他会对一些人有用。 我有一个类似的问题,我最近解决( 在这里find ),这里是我回答这个问题的步骤的亮点:
-
确保你有在PYTHONPATH(在这里和这里find更多的信息)需要的variables,你可以在.profile或者.bash_profile里面find你想testing脚本的shell,以确保它能正常工作。
-
编辑您的crontab以包含在cron作业中运行您的脚本所需的目录(在这里和这里find)
a)确保在PATHvariables(。)中包含根目录(如果这是在你的命令中运行一个可执行文件,它需要能够find根目录或可执行文件所在的目录),或许这些(/ sbin目录:/ bin中:/ usr / sbin目录:在/ usr / bin)中
-
在您的crontab文件中,创build一个cronjob,它将把目录切换到您已经成功运行脚本的目录(即Users / user / Documents / foo)
a)这将如下所示:
* * * * cd /Users/user/Documents/foo; bar -l doSomething -v
如果你不想在各个地方进行相同的编辑,那么粗略的做这个:
* * * * * . /home/username/.bashrc && yourcommand all of your args
的。 空间,然后到.bashrc和&&命令的path是在那里把你的环境改变到正在运行的bash shell。 而且,如果你真的希望shell是bash,那么在你的crontab中有一行是个好主意:
SHELL=/bin/bash
希望它可以帮助别人!
@特雷维诺:你的回答帮助我解决了我的问题。 但是,对于一个初学者来说,试图给出一个一步一步的方法。
- 通过
$ echo $JAVA_HOME
获取当前的Java安装 -
$ crontab -e
-
* * * * * echo $PATH
– 这可以让你理解目前crontab正在使用的PATH值是什么。 运行crontab并获取crontab使用的$ PATH值。 - 现在再次编辑crontab来设置你想要的java binpath:a)
crontab -e
; b)PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin
(其样本path); c)现在您的计划作业/脚本,如*/10 * * * * sh runMyJob.sh &
; d)从crontab中删除echo $PATH
,因为现在不需要它。
在webmin下,这是一个非常简单的:
System -> Scheduled Cron Jobs -> Create a new environment variable -> For user: <Select the user name> -> Variable name: PATH -> Value: /usr/bin:/bin:<your personal path> -> Add environment variable: Before all Cron jobs for user