Linux 如何让 CRON 调用正确的路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2388087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:49:56  来源:igfitidea点击:

How to get CRON to call in the correct PATHs

linuxpathcron

提问by chrissygormley

I'm trying to get cron to call in the correct PATHs. When I run a Python script from shell the script runs fine as it uses the PATHs set in bashrc but when I use cron all the PATHs are not used from bashrc. Is there a file I can enter the PATHs into for cron like bashrc or a way to call the PATHs from bashrc?

我试图让 cron 调用正确的路径。当我从 shell 运行 Python 脚本时,脚本运行良好,因为它使用了 bashrc 中设置的 PATH,但是当我使用 cron 时,所有 PATH 都没有从 bashrc 中使用。是否有一个文件我可以像 bashrc 一样为 cron 输入 PATH 或从 bashrc 调用 PATH 的方法?

Sorry I don't think I worded this correctly, I can get the correct script to run (meaning the PATH to the script in crontab is not the problem here), it's just when that script is running I run a build and this uses the PATHs set in .bashrc. When I run the script when I'm logged in, the .bashrcPATHs are pulled in. Since cron doesn't run in a shell per say it does not pull in .bashrc. Is there a way of pulling this in without having to write a bash script wrapper?

抱歉,我认为我的措辞不正确,我可以运行正确的脚本(这意味着 crontab 中脚本的 PATH 不是这里的问题),只是在该脚本运行时我运行了一个构建,这使用了中设置的路径.bashrc。当我在登录时运行脚本时,.bashrc路径被拉入。由于 cron 不在 shell 中运行,所以它不会拉入.bashrc。有没有办法在不必编写 bash 脚本包装器的情况下将其引入?

采纳答案by chrissygormley

I used /etc/crontab. I used viand entered in the PATHs I needed into this file and ran it as root. The normal crontab overwrites PATHs that you have set up. A good tutorial on how to do this.

我用过/etc/crontab。我使用vi并输入了我需要的路径到这个文件中,并以 root 身份运行它。正常的 crontab 会覆盖您设置的 PATH。关于如何做到这一点的好教程

The systemwide cron file looks like 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

回答by Douglas Leeder

You should put full paths in your crontab. That's the safest option.
If you don't want to do that you can put a wrapper script around your programs, and set the PATH in there.

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

e.g.

例如

01 01 * * * command

becomes:

变成:

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

Also anything called from cronshould be be very careful about the programs it runs, and probably set its own choice for the PATHvariable.

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

EDIT:

编辑:

If you don't know where the command is that you want execute which <command>from your shell and it'll tell you the path.

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

EDIT2:

编辑2:

So once your program is running, the first thing it should do is set PATHand any other required variable (e.g. LD_LIBRARY_PATH) to the values that are required for the script to run.
Basically instead of thinking how to modify the cron environment to make it more suitable for your program/script - make your script handle the environment it's given, by setting an appropriate one when it starts.

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

回答by mob

The default environment for cron jobs is very sparse and may be very different from the environment you develop your python scripts in. For a script that might be run in cron, any environment that you depend on should be set explicitly. In the cron file itself, include full paths to python executables and to your python scripts.

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

回答by joemaller

Most likely, cron is running in a very sparse environment. Check the environment variables cron is using by appending a dummy job which dumps envto a file like this:

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

* * * * * env > env_dump.txt

Compare that with the output of envin a normal shell session.

将其与env正常 shell 会话中的输出进行比较。

You can prepend your own environment variables to the local crontab by defining them at the top of your crontab.

您可以通过在 crontab 的顶部定义它们来将您自己的环境变量添加到本地 crontab。

Here's a quick fix to prepend $PATHto the current crontab:

这是添加$PATH到当前 crontab的快速修复:

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

The resulting crontab will look similar to chrissygormley's answer, with PATH defined before the crontab rules.

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

回答by Van Amburg

On my AIX cron picks up it's environmental variables from /etc/environment ignoring what is set in the .profile.

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

Edit: I also checked out a couple of Linux boxes of various ages and these appear to have this file as well, so this is likely not AIX specific.

编辑:我还检查了几个不同年龄的 Linux 机器,它们似乎也有这个文件,所以这可能不是特定于 AIX 的。

I checked this using joemaller's cron suggestion and checking the output before and after editing the PATH variable in /etc/environment.

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

回答by derigible

I know this has been answered already, but I thought that his would be useful to some. I had a similar issue that I recently solved (found here) and here are the highlights of the steps I took to answer this question:

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

  1. make sure that you have the variables you need in PYTHONPATH (found here and here and for more info here) inside the .profile or .bash_profile for any shell you want to test your script in to make sure it works.

  2. edit your crontab to include the directories needed to run your script in a cron job (found here and here)

    a) be sure to include the root directory in the PATH variable (.) as explained here (basically if you are running an executable with your command it needs to be able to find root or the directory where the executable is stored) and probably these (/sbin:/bin:/usr/sbin:/usr/bin)

  3. in your crontab file, create a cronjob that will change directory to the directory where you have successfully ran the script before (i.e. Users/user/Documents/foo)

    a) This will look like the following:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
  1. 确保在 .profile 或 .bash_profile 中的 PYTHONPATH 中具有所需的变量(可在此处和此处找到并在此处获取更多信息),以用于要测试脚本的任何 shell 以确保其正常工作。

  2. 编辑您的 crontab 以包含在 cron 作业中运行脚本所需的目录(可在此处和此处找到)

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

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

    a) 这将如下所示:

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

回答by Wade Chandler

If you don't want to have to make the same edits in various places, then roughly do this:

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

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

The . space and then the path to .bashrc and the && command are the magic there to get your environment changes into the running bash shell. Too, if you really want the shell to be bash, it is a good idea to have a line in your crontab:

这 。空间,然后是 .bashrc 的路径和 && 命令是将环境更改到正在运行的 bash shell 中的魔法。同样,如果您真的希望 shell 成为 bash,那么在您的 crontab 中有一行是个好主意:

SHELL=/bin/bash

Hope it helps someone!

希望它可以帮助某人!

回答by brakertech

Problem

问题

Your script works when you run it from the console but fails in cron.

当您从控制台运行脚本时,您的脚本有效,但在 cron 中失败。

Cause

原因

Your crontab doesn't have the right path variables (and possibly shell)

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

Solution

解决方案

Add your current shell and path the crontab

添加您当前的 shell 并路径 crontab

Script to do it for you

脚本来为你做

#!/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

Source

来源

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

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

Sample Output

样本输出

add_curent_shell_and_path_to_crontab.sh example output

add_curent_shell_and_path_to_crontab.sh 示例输出

回答by Trevi?o

Adding a PATH definition into the user crontab with correct values will help... I've filled mine with just:

使用正确的值将 PATH 定义添加到用户 crontab 中将有所帮助......我只填写了我的:

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

And it's enough to get all my scripts working... Include any custom path there if you need to.

这足以让我的所有脚本工作......如果需要,请在其中包含任何自定义路径。

回答by myrho

Setting PATH right before the command line in my crontab worked for me:

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

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