如何让CRON调用正确的PATH

时间:2010-03-05 16:05:49

标签: linux path cron

我正在尝试让cron调用正确的PATH。当我从shell运行Python脚本时,脚本运行正常,因为它使用bashrc中设置的PATH但是当我使用cron时,所有的PATH都没有在bashrc中使用。是否有一个文件我可以输入PATH进入cron,如bashrc或从bashrc调用PATHs的方法?

抱歉,我认为我没有正确地说这个,我可以得到正确的脚本来运行(意味着crontab中脚本的PATH不是问题),只是当脚本运行时我运行构建并且这使用.bashrc中设置的PATH。当我登录时运行脚本时,.bashrc PATH被拉入。由于cron不会在shell中运行,因此它不会引入.bashrc。有没有办法在不必编写bash脚本包装的情况下完成此操作?

15 个答案:

答案 0 :(得分:153)

我使用了/etc/crontab。我使用vi并在此文件中输入我需要的PATH并以root身份运行它。普通的crontab会覆盖您已设置的PATH。 A good tutorial on how to do this

系统范围的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

# m h 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

答案 1 :(得分:45)

最有可能的是,cron在一个非常稀疏的环境中运行。通过附加一个将env转储到这样的文件的虚拟作业来检查cron正在使用的环境变量:

* * * * * env > env_dump.txt

将它与普通shell会话中env的输出进行比较。

您可以将自己的环境变量添加到本地crontab,方法是在crontab的顶部定义它们。

这是一个快速修复,可以将$PATH添加到当前的crontab:

# echo PATH=$PATH > tmp.cron
# echo >> tmp.cron
# crontab -l >> tmp.cron
# crontab tmp.cron

生成的crontab看起来类似于chrissygormley的回答,在crontab规则之前定义了PATH。

答案 2 :(得分:20)

您应该在crontab中添加完整路径。这是最安全的选择。
如果您不想这样做,可以在程序周围放置一个包装器脚本,并在那里设置PATH。

e.g。

01 01 * * * command

变为:

01 01 * * * /full/path/to/command

cron调用的任何内容都应该对它运行的程序非常小心,并且可能为PATH变量设置自己的选择。

编辑:

如果您不知道命令的位置,您希望从shell执行which <command>,它会告诉您路径。

EDIT2:

因此,一旦程序运行,它应该做的第一件事就是将PATH和任何其他必需变量(例如LD_LIBRARY_PATH)设置为脚本运行所需的值。 /> 基本上没有考虑如何修改cron环境以使其更适合您的程序/脚本 - 让脚本处理它给出的环境,通过在启动时设置适当的环境。

答案 3 :(得分:14)

让你的变量适合你,这将允许访问t

在/etc/profile.d / *中定义您的PATH。sh

System-wide environment variables

/etc/profile.d目录中带有.sh扩展名的文件在输入bash登录shell时(例如,从控制台或通过ssh登录时)以及桌面会话时由DisplayManager执行负荷。

您可以创建文件/etc/profile.d/myenvvars.sh并设置如下变量:

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$JAVA_HOME/bin

使用登录选项执行crontab!

CRONTAB run script or command with Environment 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

答案 4 :(得分:13)

在我的crontab命令行之前设置PATH对我有用:

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing

答案 5 :(得分:10)

问题

当您从控制台运行脚本但在cron中失败时,您的脚本会正常工作。

原因

您的crontab没有正确的路径变量(可能还有shell)

解决方案

添加当前shell和路径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 example output

答案 6 :(得分:10)

使用正确的值将PATH定义添加到用户crontab中将有助于...... 我只是填补了我的一切:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

这足以使我的所有脚本都正常工作......如果需要,可以在那里包含任何自定义路径。

答案 7 :(得分:3)

在我的AIX上,cron从/ etc / environment中获取环境变量,忽略.profile中设置的内容。

编辑:我还检查了几个不同年龄的Linux盒子,这些盒子似乎也有这个文件,所以这可能不是AIX特有的。

我使用joemaller的cron建议检查了这一点,并在/ etc / environment中编辑PATH变量之前和之后检查输出。

答案 8 :(得分:2)

cron作业的默认环境非常稀疏,可能与您开发python脚本的环境有很大不同。对于可能在cron中运行的脚本,应该明确设置您依赖的任何环境。在cron文件本身中,包括python可执行文件和python脚本的完整路径。

答案 9 :(得分:2)

我知道这已经得到了解答,但我认为他对某些人有用。我有一个类似的问题,我最近解决了(found here),这里是我回答这个问题的步骤的重点:

  1. 确保您在PYTHONPATH中找到所需的变量(在此处和此处获取以及此处的更多信息),在.profile或.bash_profile中为您要测试脚本的任何shell确保其有效

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

    a)确保将根目录包含在PATH变量(。)中,如此处所述(基本上,如果您使用命令运行可执行文件,则需要能够找到root或存储可执行文件的目录)可能这些(/ sbin:/ bin:/ usr / sbin:/ usr / bin)

  3. 在您的crontab文件中,创建一个cronjob,它将目录更改为您之前成功运行该脚本的目录(即Users / user / Documents / foo)

    a)这将如下所示:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    

答案 10 :(得分:2)

如果您不想在不同的地方进行相同的编辑,那么大致可以这样做:

* * * * * . /home/username/.bashrc && yourcommand all of your args

。空间然后是.bashrc和&amp;&amp;的路径命令是将环境变为运行的bash shell的神奇之处。太,如果你真的想要shell是bash,最好在你的crontab中有一行:

SHELL=/bin/bash

希望它有所帮助!

答案 11 :(得分:2)

我找到的最简单的解决方法如下:

* * * * * root su -l -c command

此示例以root用户身份调用su并以用户的完整环境(包括$ PATH)启动外壳程序,该环境设置为就像他们已登录一样。在不同发行版中的作用相同,比sourcing更为可靠。 bashrc(对我而言不起作用),避免了对特定路径进行硬编码,如果您提供的是示例或设置工具并且不知道用户系统上的发行版或文件布局,则可能会出现问题。

如果您想要的用户名不同于root用户,也可以在su之后指定用户名,但是您可能应该在root命令之前保留su参数,因为这样可以确保{{1} }具有足够的特权可以切换到您指定的任何用户。

答案 12 :(得分:1)

@Trevino:你的回答帮助我解决了我的问题。但是,对于初学者来说,尝试一步一步的方法。

  1. 通过$ echo $JAVA_HOME
  2. 获取当前的java安装
  3. $ crontab -e
  4. * * * * * echo $PATH - 这让您了解目前crontab使用的PATH值是什么。运行crontab并获取crontab使用的$ PATH值。
  5. 现在再次编辑crontab以设置所需的java bin路径:a)crontab -e; b)PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin(它的样本路径); c)现在你的预定工作/脚本如*/10 * * * * sh runMyJob.sh &; d)从crontab中删除echo $PATH,因为它现在不需要。

答案 13 :(得分:0)

在cron中设置所需的PATH

crontab -e

修改:按i

PATH=/usr/local/bin:/usr/local/:or_whatever

10 * * * * your_command

保存并退出:wq

答案 14 :(得分:-3)

如果您使用webmin,那么以下是设置PATH值的步骤:

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