首页 文章

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

提问于
浏览
228

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

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

12 回答

  • 2

    让'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
    
  • 220

    从命令行运行 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,其中 does not 允许声明环境变量,并将在cron.log中引发语法错误 . 解决方法可以按条目完成:

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

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

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

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

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

  • 39

    /etc/environment 中设置变量也在Ubuntu中为我工作 . 从12.04开始, /etc/environment 中的变量被加载为cron .

  • 12

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

  • 76

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

    我希望这有帮助!

  • 19

    如果您启动脚本,则通过cron执行:

    #!/bin/bash -l
    

    他们应该拿起你的 ~/.bash_profile 环境变量

  • 13

    您在_2665107中设置的内容将在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
    ...
    
  • 10

    代替

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

    使用bash -l -c

    0  *  *  *  *  bash -l -c 'sh /my/script.sh'
    
  • 2

    扩展@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
    
  • 4

    另一种方式 - 灵感来自this answer - 到"inject"变量如下(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
    
  • 5

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

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

    这基本上是 case statement ,它检查当前shell中的当前选项集,以确定shell是以交互方式运行的 . 如果shell碰巧以交互方式运行,那么它将继续采购 ~/.bashrc 文件 . 但是,在 cron 调用的shell中, $- 变量不包含指示交互性的 i 值 . 因此, ~/.bashrc 文件永远不会完全来源 . 因此,环境变量永远不会被设置 . 如果这恰好是您的问题,请随意注释掉代码块,然后重试:

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

    我希望这有用

相关问题