如何让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调用的任何东西都应该对它运行的程序非常小心,并可能为PATHvariables设置自己的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 

资源

https://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

示例输出

add_curent_shell_and_path_to_crontab.sh示例输出

用正确的值添加一个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 ),这里是我回答这个问题的步骤的亮点:

  1. 确保你有在PYTHONPATH(在这里和这里find更多的信息)需要的variables,你可以在.profile或者.bash_profile里面find你想testing脚本的shell,以确保它能正常工作。

  2. 编辑您的crontab以包含在cron作业中运行您的脚本所需的目录(在这里和这里find)

    a)确保在PATHvariables(。)中包含根目录(如果这是在你的命令中运行一个可执行文件,它需要能够find根目录或可执行文件所在的目录),或许这些(/ sbin目录:/ bin中:/ usr / sbin目录:在/ usr / bin)中

  3. 在您的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 

希望它可以帮助别人!

@特雷维诺:你的回答帮助我解决了我的问题。 但是,对于一个初学者来说,试图给出一个一步一步的方法。

  1. 通过$ echo $JAVA_HOME获取当前的Java安装
  2. $ crontab -e
  3. * * * * * echo $PATH – 这可以让你理解目前crontab正在使用的PATH值是什么。 运行crontab并获取crontab使用的$ PATH值。
  4. 现在再次编辑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