我每小时都有一个crontab。运行它的用户在.bash_profile
中具有环境变量,当用户从终端运行作业时,该变量可用,但是,显然这些变量在运行时不被crontab拾取。
我已尝试在.profile
和.bashrc
中设置它们,但它们似乎仍然没有被提升。有谁知道我可以把crontab可以拿到的环境变量放在哪里?
答案 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)中声明它们。
Archlinux和RedHat使用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中直接使用,并且可以使用脚本中的变量。
您可以配置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
...
答案 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):
创建一个包含所有需要的环境变量的文件:
#!/bin/bash
环境 | grep VAR1= > /etc/environment
环境 | grep VAR2= >> /etc/environment
环境 | grep VAR3= >> /etc/environment
然后构建 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