脚本由 cron 运行时的环境变量

Environment Variables when script run by cron

提问人: 提问时间:2/8/2017 最后编辑:tripleee 更新时间:7/4/2022 访问量:33268

问:

我有一个使用环境变量的 Python 脚本。此脚本在直接运行时完全按计划工作;但是,我想暂时每分钟将其作为 cron 作业运行一次。

目前在我的目录中,我有一个名为的文件,其中包含:cron.scrapers

* * * * * root /usr/bin/python3.5 /code/scraper.py

这将运行 Python 脚本,但脚本失败,因为在脚本中我使用了两个环境变量。

我读到我应该添加到 cron 文件中,所以我做到了,但这没有帮助。SHELL=/bin/bash

SHELL=/bin/bash
* * * * * root /usr/bin/python3.5 /code/scraper.py

然后我读了

在 crontab 中,在命令之前,添加 .. $HOME/.profile

SHELL=/bin/bash
* * * * * . $HOME/.profile; root /usr/bin/python3.5 /code/scraper.py

但这导致 cron 完全停止运行。将 env 变量“发送”到 cron 的最佳方式是什么?

python linux cron 环境变量

评论

1赞 franklinsijo 2/8/2017
尝试添加或声明 env 变量的文件,看看它是否有效。source ~/.bashrc && command
0赞 2/8/2017
@franklinsijo 对不起,我不太确定我应该做什么。设置容器时,env 变量在 docker-compose 文件中声明。
0赞 franklinsijo 2/8/2017
这些变量是 scraper.py 要使用的变量吗?
0赞 2/8/2017
@franklinsijo是的。
1赞 franklinsijo 2/8/2017
AFAIK,必须在文件(配置文件)中设置环境变量,即使在会话关闭后仍然可用。或者,您可以使用命令来设置该会话的变量。export

答:

4赞 fabiocerqueira 2/11/2017 #1

您可以内联设置 env 变量:

* * * * * root ENV_VAR=VALUE /usr/bin/python3.5 /code/scraper.py

另一种方法是使用 honcho,您可以传递带有 env 变量的文件。

honcho -e /path/to/.env run /code/scraper.py

评论

0赞 2/11/2017
有没有办法让所有 env 值都通过 cron?
0赞 fabiocerqueira 2/11/2017
Env 变量继承自父进程。
12赞 Louis 2/11/2017 #2

我所做的不是全部执行,而是移动必须在您的作业和具有配置文件的帐户之间共享的变量,然后我会在 cron 作业中和在 cron 作业中获取这些变量。~/.profilecron~/.profile

您在问题中显示的最后一次尝试的格式不正确。用户 ID 应该紧跟在计划信息之后,但您在用户 ID 之前添加了配置文件的来源,这肯定行不通。

以下是我在这里测试的示例设置:

*/1 * * * * someuser . /tmp/t10/setenv && /usr/bin/python /tmp/t10/test.py

出于测试目的,我将其设置为每分钟执行一次。替换为有意义的东西。我使用的脚本是这样的:someuser/tmp/t10/setenv

export FOO=foovalue
export BAR=barvalue

该文件有这个:/tmp/t10/test.py

import os

print os.environ["FOO"], os.environ["BAR"]

我的 cron 通过电子邮件向我发送它运行的脚本的输出。我收到一封电子邮件,其中包含以下输出:

foovalue barvalue

评论

1赞 Gang 2/18/2017
setenv && test.py,相当于 in 的系统调用,它会而且肯定会起作用,比我更好的方法是将 test.py 的系统调用放在一个文件中。我喜欢这种方法。test.pysetenv
0赞 LoMaPh 1/1/2022
为什么要采购它?采购还不够吗?~/.profile
0赞 Louis 1/4/2022
如果你仍然希望你像以前一样工作,你必须把它采购进来。如果你不想要它,那么你不必在 .~/.profile~/.profile~/.profile
0赞 Mario Parra 7/4/2022
我正在尝试实现它,因为我使用 ,但它不起作用。我有两个 env var,我的 .py 文件源并使用 读取它们,这是我的 cron 工作:.问题是当我在 cron 作业中获取两个变量时,我都会得到它们;它们在 VS Code 中仍然正确。最初,cron 作业告诉我 存在权限错误,但我修复了它,所以我知道它正在读取它。我无法使用用户名完成工作zsh~/.env.envos.environ*/2 * * * * ~/.env && ~/Documents/Dev/site_monitor/monitor_env/bin/python ~/Documents/Dev/site_monitor/monitor.pyNoneprintprint.env
1赞 tripleee 7/4/2022
@MarioParra 您缺少之前的(源)。没有它,您将在子 shell 中运行,该子 shell 的变量在退出时将不复存在,因此它们对作业的其余部分不可用。.~/.env.envcron
2赞 Kirill Bulygin 2/11/2017 #3

您可以通过以下方式指定两个环境变量:

* * * * * root env A=1 B=2 /usr/bin/python3.5 /code/scraper.py

env是一个系统程序,它运行具有附加变量的指定程序:

$ env A=1 B=2 /bin/sh -c 'echo $A$B'  # or just 'sh': would search in $PATH
12
1赞 Gang 2/12/2017 #4

这是我喜欢的方法之一,编写脚本来设置环境并以其参数作为参数执行脚本

set_env_to_process.sh

#!/usr/bin/env bash
echo "TEST_VAR before export is: <$TEST_VAR>"

export TEST_VAR=/opt/loca/netcdf
echo "TEST_VAR after export is: <$TEST_VAR>"
export PATH=$PATH:/usr/bin/python3.5
export PYTHTONPATH=$PYTHONPATH:/my/installed/pythonpath

# execute command and its parameters as input for this script
if [ $# -eq 0 ]; then
    echo "No command to execute"
else
    echo "Execute commands with its parameters: $@"
    eval $@
fi

用法

/usr/bin/python3.5 /code/scraper.py作为设置要运行的脚本的正确环境的输入set_env_to_process.shset_env_to_process.sh

它可以用作命令行,cron,sudo,ssh来设置环境

 * * * * * root set_env_to_process.sh /usr/bin/python3.5 /code/scraper.py
4赞 Scott Skiles 6/30/2018 #5

您可以将其添加到crontab的顶部,并将其排除在版本控制之外。假设导致您困难的环境变量是:export DJANGO_SECRET_KEY="FOOBAR_1241243124312341234"

克罗塔布

DJANGO_SECRET_KEY="FOOBAR_1241243124312341234"

SCRIPT_NAME = my_cool_script
20 21 * * 1-5 bash ~/git_repo/cronjobs/$SCRIPT_NAME.sh 2&>1 | tee ~/git_repo/cronjobs/logs/$SCRIPT_NAME.log

my_cool_script.sh

#!/usr/bin/env bash
~/anaconda3/envs/django/bin/python ~/git_repo/django_project/manage.py run_command

当所讨论的环境变量需要保密并且由于某种原因加载现有 .bashrc 时,这对我来说效果很好。