我在哪里可以设置crontab将使用的环境变量?

时间:2010-02-09 14:39:12

标签: linux unix environment-variables crontab

我每小时都有一个crontab。运行它的用户在.bash_profile中具有环境变量,当用户从终端运行作业时,该变量可用,但是,显然这些变量在运行时不被crontab拾取。

我已尝试在.profile.bashrc中设置它们,但它们似乎仍然没有被提升。有谁知道我可以把crontab可以拿到的环境变量放在哪里?

20 个答案:

答案 0 :(得分:222)

从命令行运行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)中声明它们。

ArchlinuxRedHat使用cronie 允许声明环境变量,并在cron.log中引发语法错误。解决方法可以按条目完成:

# m h  dom mon dow   command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"

答案 1 :(得分:129)

我还有一个解决这个问题的方法:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

在这种情况下,它将选择$ HOME / .profile文件中定义的所有环境变量。

当然$ HOME也没有设置,你必须用$ HOME的完整路径替换它。

答案 2 :(得分:79)

让'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版本。因此,例如,我的'weekday'命令看起来像:

:       "@(#)$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

答案 3 :(得分:41)

Mat gaborCoeff = Imgproc.getGaborKernel(new Size(3,3), sigma, theta[i], lambda, psi, 0, CvType.CV_32F); 中设置变量也在Ubuntu中对我有用。从12.04开始,/etc/environment中的变量被加载为cron。

答案 4 :(得分:21)

扩展@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源之后的任何命令都会像您登录一样拥有您的环境。

答案 5 :(得分:14)

如果启动脚本,您将通过cron执行以下操作:

#!/bin/bash -l

他们应该选择您的~/.bash_profile环境变量

答案 6 :(得分:14)

对我来说,我必须为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"

我希望这有帮助!

答案 7 :(得分:10)

您在crontab中设置的内容将在cronjobs中直接使用,并且可以使用脚本中的变量。

在cronjob

的定义中使用它们

您可以配置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

在cronjob

运行的脚本中使用它们

您可以配置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
...

答案 8 :(得分:5)

而不是

Just

使用bash -l -c

0  *  *  *  *  sh /my/script.sh

答案 9 :(得分:4)

扩展@Robert Brisita刚刚扩展,如果你不想在脚本中设置配置文件的所有变量,你可以选择要在脚本顶部导出的变量

在crontab -e文件中:

SHELL=/bin/bash

*/1 * * * * /Path/to/script/script.sh

在script.sh

#!/bin/bash
export JAVA_HOME=/path/to/jdk

some-other-command

答案 10 :(得分:3)

我在Macbook中使用Oh-my-zsh,所以我尝试了很多事情来使crontab任务运行,但是最终,我的解决方案是在运行命令之前加.zshrc

*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js

此任务每30分钟运行一次,并使用.zshrc配置文件执行我的节点命令。

不要忘记在$HOME变量前使用点。

答案 11 :(得分:3)

您还可以在命令前加上env来注入环境变量,如下所示:

0 * * * *   env VARIABLE=VALUE /usr/bin/mycommand

答案 12 :(得分:2)

另一种方式 - 受此this answer的启发 - 注入&#34;变量如下(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 vars以格式化电子邮件标头的示例:

su -s /bin/bash -c "set -a; \
                    . /path/to/nullmailer-vars; \
                    set +a; \
                    /usr/sbin/logcheck" logcheck

答案 13 :(得分:2)

我尝试了提供的大多数解决方案,但一开始没有任何效果。但是事实证明,并非解决方案无法奏效。显然,我的~/.bashrc文件以以下代码块开头:

case $- in
    *i*) ;;
    *) return;;
esac

这基本上是一个case statement,它检查当前shell中的当前选项集以确定该shell正在交互运行。 如果外壳碰巧正在以交互方式运行,那么它将继续采购~/.bashrc文件。 但是,在cron调用的shell中,$-变量不包含表示交互性的i值。 因此,~/.bashrc文件永远不会获得完整的来源。结果,从未设置环境变量。 如果碰巧是您的问题,请按照以下说明随意注释代码块,然后重试:

# case $- in
#     *i*) ;;
#     *) return;;
# esac

我希望这对我们有用

答案 14 :(得分:0)

对我来说,我必须在NodeJS文件中指定路径。

// did not work!!!!!
require('dotenv').config()

代替

// DID WORK!!
require('dotenv').config({ path: '/full/custom/path/to/your/.env' })

答案 15 :(得分:0)

不幸的是,crontabs的环境变量范围非常有限,因此您需要在每次corntab运行时将其导出。

下面的示例是一个简单的方法,假设您将env vars保存在名为env的文件中,然后:

* * * * * . ./env && /path/to_your/command

这部分. ./env将导出它们,然后在您命令的相同范围内使用它们

答案 16 :(得分:0)

  • 设置全局环境
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"

=)

答案 17 :(得分:0)

以上所有解决方案都可以正常工作。

当环境变量中有任何特殊字符时,它将产生问题。

我找到了解决方法:

eval $(printenv | awk -F= '{print "export " "\""$1"\"""=""\""$2"\"" }' >> /etc/profile)

答案 18 :(得分:0)

什么对我有用(基于 debian):

  1. 创建一个包含所有需要的环境变量的文件:

    #!/bin/bash
    环境 | grep VAR1= > /etc/environment
    环境 | grep VAR2= >> /etc/environment
    环境 | grep VAR3= >> /etc/environment

  2. 然后构建 crontab 内容,通过在调用需要它的脚本之前调用 env 文件,从而启动 cron 服务

    (crontab -l ; echo '* * * * * . /etc/environment; /usr/local/bin/python /mycode.py >> /var/log/cron-1.log 2>&1') |定时任务
    服务 cron 启动

nb : 对于python用例,一定要调用整个python路径,否则可能会调用错误的python,产生无意义的语法错误

答案 19 :(得分:0)

我在查看与标题匹配的类似问题时发现了这个问题,但我坚持使用 systemd 或 docker 使用的环境文件语法:

FOO=bar
BAZ=qux

这不适用于 Vishal's excellent answer,因为它们不是 bash 脚本(请注意缺少 export)。
我使用的解决方案是在运行命令之前将每一行读入 xargs 并导出它们:

0 5 * * * export $(xargs < $HOME/.env); /path/to/command/to/run