我试图让cron调用正确的PATH。当我从外壳运行Python脚本时,脚本运行良好,因为它使用了bashrc中设置的PATH,但是当我使用cron时,bashrc中并未使用所有PATH。

对不起,我认为我的措词不正确,我可以获取正确的脚本来运行(这意味着crontab中脚本的路径不是这里的问题),只是该脚本正在运行时,我运行了构建,并且使用了.bashrc中设置的PATH。登录后运行脚本时,会插入.bashrc PATH。由于cron不在外壳程序中运行,因此说不会插入.bashrc。有没有一种方法可以不必编写bash脚本包装程序而将其引入?

评论

也可以看看这里给出的关于如何使bashrc设置适用于cronjobs的建议:stackoverflow.com/q/15557777/1025391

使您的配置文件包含在当前环境中的神奇,简单且正确的命令是源/ etc / profile,它应该吃掉.bashrc和许多其他可能会丢失的东西。如果您希望某些脚本“独立”运行,则明确的配置文件来源非常有用,它还可以防止怪异的环境,因此...

@exa +100这使crontab调用的sh脚本起作用。您可以通过添加作业,例如* * * * * echo $ PATH>〜/ crontab_path.txt并在一分钟后检查文件来确认它更新了路径。

#1 楼

我用/etc/crontab。我使用了vi,并在该文件中输入了所需的PATH,然后以root身份运行了该文件。普通的crontab会覆盖您设置的PATH。一个很好的有关如何执行此操作的教程。

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


评论


这可以在用户级别与crontab -e一起使用,并且这样做也更安全。

– Robert Brisita
2013年9月5日在22:28

我可以使用bash代替sh吗?

– q
13年11月29日在21:55

对我来说,很奇怪的是,在/ etc / crontab中设置的默认路径(如@chrissygormley所示)以及在我的(Ubuntu)crontab中设置的默认路径与/ etc / environment中的路径不同,特别是将/ sbin和/ bin位于/ usr / sbin和/ usr / bin之前。我现在已经在/ etc / crontab中对此进行了更改,使其与用户环境相同。

–scoobydoo
15年4月22日在6:17

对我不起作用..我正在将cron内容输出到文件中。 Cron运行,创建文件,但未在其中添加任何内容。

– Volatil3
15年7月31日在6:08

在Ubuntu 14.04中以root身份运行时,似乎并非/ etc / crontab中设置的所有路径都对cron可用。 (须藤crontab -e)

–大卫·奥利弗(David Oliver)
17年1月26日在12:49

#2 楼

cron很可能在非常稀疏的环境中运行。通过在cron中添加一个伪作业来检查cron正在使用的环境变量,该伪作业将env转储到类似以下文件的文件中:

* * * * * 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。

#3 楼

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

例如

01 01 * * * command


变成:

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


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

编辑:

如果您不知道命令在哪里,则要从shell中执行which <command>,它将告诉您路径。

EDIT2:

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

评论


如果它在您的路径中使用“哪个命令”,它将为您提供完整的路径

– Paul Whelan
2010-3-5在16:09



@Douglas Leeder-当您说将完整路径放入cron时,是指将其放入crontab或另一个文件中吗?如果是cron命令,则如何处理:'01 01 * * * command'。谢谢

–基督
2010年3月5日在16:13

@chrissygormley-是的crontab。

–道格拉斯·里德(Douglas Leeder)
2010-3-5在16:31

抱歉,一定有些混乱。我已经改写了上面的问题。

–基督
2010-3-5在17:08

#4 楼

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

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


评论


喜欢这种方式。或指定脚本的完整路径。

– zw963
17年4月13日在13:29

我不认为路径会持续增长,每次运行都会是一个新环境,并带有PATH的新副本...

– jjcf89
19年1月28日在16:07

可以确认@ jjcf89是正确的,每次运行时PATH都是新鲜的。

– Electrovir
19/12/4在18:20

#5 楼

让您的变量为您工作,这将允许访问t

在/etc/profile.d/*.sh

中定义系统路径

每次输入bash登录shell(例如,从控制台或ssh登录时)时,都将执行/etc/profile.d目录中具有.sh扩展名的文件,而在输入桌面会话加载。

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

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


使用登录选项执行crontab!

带有环境变量的CRONTAB运行脚本或命令

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


#6 楼

将具有正确值的PATH定义添加到用户crontab中将有助于...
我用以下命令填充了我的代码:

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


就足够了我所有的脚本都在工作...如果需要,请在其中包括任何自定义路径。

评论


对于crontab用户,这应该是正确的答案。并非系统上的每个人都可以编辑/ etc / crontab。这是在用户级别上最简单的答案。干得好@Treviño。如果您同意,请对此投票。

– frederickjh
19年8月8日,11:45



#7 楼

问题

您的脚本从控制台运行时可以运行,但是在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 "; }
function print_good { echo -e "\x1B[01;32m[*]\x1B[0m "; }
function print_error { echo -e "\x1B[01;31m[*]\x1B[0m "; }
function print_notification { echo -e "\x1B[01;33m[*]\x1B[0m "; }
function printline { 
  hr=-------------------------------------------------------------------------------------------------------------------------------
  printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"
}
####################################
# print message and exit program
function die { print_error ""; 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

样品输出



#8 楼

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

#9 楼

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

编辑:我还签出了几个不同年龄的Linux盒,它们看起来也都有此文件,因此这可能不是特定于AIX的。

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

#10 楼

如果您不想在各个地方进行相同的编辑,请大致执行以下操作:

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


。空格,然后是.bashrc的路径以及&&命令,是将环境更改为正在运行的bash shell的神奇之处。同样,如果您真的希望shell受到重击,那么在crontab中插入一行也是个好主意:

SHELL=/bin/bash


希望对别人有帮助!

#11 楼

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


请确保您拥有所需的变量.profile或.bash_profile内的PYTHONPATH(在此处和此处以及在此处了解更多信息),用于要在其中测试脚本以确保其工作的任何shell。

编辑crontab以包括目录在cron作业中运行脚本所需的信息(请在此处和此处找到)

a)确保按此说明在PATH变量(。)中包含根目录(基本上,如果您正在运行可执行文件使用您的命令,它必须能够找到根目录或可执行文件的存储目录),并且可能是这些目录(/ sbin:/ bin:/ usr / sbin:/ usr / bin)


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

a)看起来像以下:
* * * * cd /Users/user/Documents/foo; bar -l doSomething -v 




#12 楼

@Trevino:您的回答帮助我解决了我的问题。但是,对于初学者,请尝试逐步解决问题。


通过$ echo $JAVA_HOME获得当前的Java安装

$ crontab -e

* * * * * echo $PATH-这可以让您了解正在使用的PATH值是什么目前是crontab。运行crontab并获取crontab使用的$ PATH值。
现在再次编辑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 楼

在cron中设置所需的PATH

crontab -e


编辑:按i

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

10 * * * * your_command


保存并退出:wq

#14 楼

我发现的最简单的解决方法是这样的:

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


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

如果您想要除root用户之外的其他用户,也可以在su之后指定用户名,但您可能应该在前面保留root参数su命令,因为这可确保su具有足够的特权以切换到您指定的任何用户。

#15 楼

如果您使用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