我每小时运行一个 crontab。当用户从终端运行作业时,运行它的用户在工作中具有环境变量.bash_profile
,但是,显然这些在运行时不会被 crontab 拾取。
我试过把它们放进去.profile
,.bashrc
但它们似乎仍然没有被捡起。有谁知道我可以在哪里放置 crontab 可以获取的环境变量?
我每小时运行一个 crontab。当用户从终端运行作业时,运行它的用户在工作中具有环境变量.bash_profile
,但是,显然这些在运行时不会被 crontab 拾取。
我试过把它们放进去.profile
,.bashrc
但它们似乎仍然没有被捡起。有谁知道我可以在哪里放置 crontab 可以获取的环境变量?
crontab -e
从命令行运行时,您可以在 crontab 本身中定义环境变量。
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h dom mon dow command
* * * * * sleep 5s && echo "yo"
此功能仅适用于 cron 的某些实现。Ubuntu 和 Debian 当前使用vixie-cron,它允许在 crontab 文件(也是 GNU mcron)中声明这些。
Archlinux和RedHat使用cronie,它不允许声明环境变量,并且会在 cron.log 中抛出语法错误。解决方法可以按条目完成:
# m h dom mon dow command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
对于这个问题,我还有另一种解决方案:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
在这种情况下,它将选择$HOME/.profile
文件中定义的所有环境变量。
当然$HOME
也没有设置,你必须用你的完整路径替换它$HOME
。
/etc/environment
在 Ubuntu中设置 vars也适用于我。从 12.04 开始,/etc/environment
为 cron 加载变量。
在运行命令之前让“cron”运行一个设置环境的 shell 脚本。
总是。
# @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
# Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min Hour Day Month Weekday Command
#-----------------------------------------------------------------------------
0 * * * * /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1 1 * * * /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23 1 * * 1-5 /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2 3 * * 0 /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21 3 1 * * /usr/bin/ksh /work1/jleffler/bin/Cron/monthly
~/bin/Cron 中的脚本都是指向单个脚本“runcron”的链接,如下所示:
: "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
# Commands to be performed by Cron (no debugging options)
# Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile
base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base
if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi
exec $cmd ${@:+"$@"}
(使用较旧的编码标准编写 - 现在,我会在开头使用 shebang '#!'。)
'~/.cronfile' 是我的配置文件中的一个变体,供 cron 使用 - 严格非交互式且没有回声,以免产生噪音。您可以安排执行 .profile 等等。(REAL_HOME 的东西是我的环境的产物——你可以假装它和 $HOME 一样。)
因此,此代码读取适当的环境,然后从我的主目录执行命令的非 Cron 版本。因此,例如,我的“工作日”命令如下所示:
: "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
# Commands to be done each weekday
# Update ICSCOPE
n.updics
'daily' 命令更简单:
: "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
# Commands to be done daily
# Nothing -- most things are done on weekdays only
exit 0
如果您通过 cron 启动正在执行的脚本:
#!/bin/bash -l
他们应该选择你的~/.bash_profile
环境变量
扩展 @carestad 示例,我发现它更容易,是使用 cron 运行脚本并在脚本中包含环境。
在 crontab -e 文件中:
SHELL=/bin/bash
*/1 * * * * $HOME/cron_job.sh
在 cron_job.sh 文件中:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd
.bash_profile 源之后的任何命令都将拥有您的环境,就好像您已登录一样。
对我来说,我必须为 php 应用程序设置环境变量。我通过将以下代码添加到我的 crontab 来解决它。
$ sudo crontab -e
crontab:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
在 doSomethingWonderful.php 里面我可以得到环境值:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
我希望这有帮助!
您设置的任何内容crontab
都将在 cronjobs 中可用,既可以直接使用,也可以使用脚本中的变量。
您可以进行配置crontab
,以便它设置然后可以 cronjob 使用的变量:
$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello
现在该文件/tmp/hello
显示如下内容:
$ cat /tmp/hello
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016
您可以进行配置crontab
,以便它设置脚本可以使用的变量:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
说脚本/tmp/myscript.sh
是这样的:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
它生成一个文件/tmp/myoutput.res
,显示:
$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...
代替
0 * * * * sh /my/script.sh
使用 bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
你也可以在你的命令前面加上env
注入环境变量,如下所示:
0 * * * * env VARIABLE=VALUE /usr/bin/mycommand
扩展@Robert Brisita 刚刚扩展,如果您不想在脚本中设置配置文件的所有变量,您可以在脚本顶部选择要导出的变量
在 crontab -e 文件中:
SHELL=/bin/bash
*/1 * * * * /Path/to/script/script.sh
在脚本.sh
#!/bin/bash
export JAVA_HOME=/path/to/jdk
some-other-command
我Oh-my-zsh
在我的 macbook 中使用,所以我尝试了很多方法来运行 crontab 任务,但最后,我的解决方案是.zshrc
在命令运行之前添加。
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
此任务每 30 分钟运行一次,并使用.zshrc
配置文件执行我的节点命令。
不要忘记在$HOME
var 之前使用点。
另一种方法-受this answer启发-“注入”变量如下(fcron示例):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
来自help set
:
-a 标记为导出而修改或创建的变量。
使用 + 而不是 - 会导致这些标志被关闭。
因此,介于两者之间的所有内容都set -
被set +
导出到env
然后可用于其他脚本等。不使用set
变量获取源但set
仅存在。
除此之外,当程序需要非 root 帐户运行但您需要其他用户环境中的一些变量时,传递变量也很有用。下面是一个传递 nullmailer 变量以格式化电子邮件标题的示例:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
我尝试了大多数提供的解决方案,但一开始没有任何效果。然而,事实证明,不是解决方案不起作用。显然,我的~/.bashrc
文件以以下代码块开头:
case $- in
*i*) ;;
*) return;;
esac
这基本上是case statement
检查当前 shell 中的当前选项集以确定 shell 交互运行。如果 shell 碰巧以交互方式运行,那么它会继续寻找~/.bashrc
文件。但是,在由 调用的 shell 中cron
,$-
变量不包含i
指示交互性的值。因此,该~/.bashrc
文件永远不会得到完全的来源。结果,环境变量从未设置。如果这恰好是您的问题,请随时注释掉代码块,如下所示,然后重试:
# case $- in
# *i*) ;;
# *) return;;
# esac
我希望这变得有用
不幸的是,crontabs 的环境变量范围非常有限,因此每次运行corntab 时都需要导出它们。
一个简单的方法是下面的例子,假设你的环境变量在一个名为 env 的文件中,那么:
* * * * * . ./env && /path/to_your/command
这部分. ./env
将导出它们,然后在您的命令的相同范围内使用它们
对我来说,我必须在我的 NodeJS 文件中指定路径。
// did not work!!!!!
require('dotenv').config()
反而
// DID WORK!!
require('dotenv').config({ path: '/full/custom/path/to/your/.env' })
以上所有解决方案都可以正常工作。
当您的环境变量中有任何特殊字符时,它会产生问题。
我找到了解决方案:
eval $(printenv | awk -F= '{print "export " "\""$1"\"""=""\""$2"\"" }' >> /etc/profile)
我在查看与标题匹配的类似问题时发现了这个问题,但我坚持使用 systemd 或 docker 使用的环境文件语法:
FOO=bar
BAZ=qux
这不适用于Vishal 的出色答案,因为它们不是 bash 脚本(注意缺少export
)。
我使用的解决方案是在运行命令之前将每一行读入 xargs 并导出它们:
0 5 * * * export $(xargs < $HOME/.env); /path/to/command/to/run
sudo sh -c "echo MY_GLOBAL_ENV_TO_MY_CURRENT_DIR=$(pwd)" >> /etc/environment"
crontab -e
*/5 * * * * sh -c "$MY_GLOBAL_ENV_TO_MY_CURRENT_DIR/start.sh"
=)
什么对我有用(基于debian):
创建一个包含所有需要的 env var 的文件:
#!/bin/bash
环境 | grep VAR1= > /etc/environment
env | grep VAR2= >> /etc/environment
env | grep VAR3= >> /etc/environment
然后通过在调用需要它的脚本之前调用 env 文件来构建 crontab 内容,因此启动 cron 服务
(crontab -l ; echo '* * * * * . /etc/environment; /usr/local/bin/python /mycode.py >> /var/log/cron-1.log 2>&1') | crontab
服务 cron 启动
注意:对于python用例,一定要调用整个python路径,否则可能会调用错误的python,产生无意义的语法错误