.bash_profile
中具有环境变量,当用户从终端运行该任务时,该变量可以工作,但是显然,crontab在运行时不会被这些变量吸收。我已经尝试过在
.profile
和.bashrc
中设置它们,但它们似乎仍然没有被拾取。有谁知道我可以将crontab可以接收的环境变量放在哪里?#1 楼
在运行命令之前,让'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 : "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
# Commands to be done each weekday
# Update ICSCOPE
n.updics
`
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: 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
“每日”命令更简单:
q4312078q
#2 楼
从命令行运行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"
#3 楼
对于这个问题,我还有一个解决方案:0 5 * * * . $HOME/.profile; /path/to/command/to/run
在这种情况下,它将选择
$HOME/.profile
文件中定义的所有环境变量。当然也没有设置
$HOME
,您必须用$HOME
的完整路径替换它。评论
经过很多努力寻找答案后,这对我有用,谢谢!
–vladimir montealegre
2012年12月27日在21:30
直到我意识到我没有在$ HOME之前的那段时间,这对我没有用。那段时间到底是做什么的?
–flymike
2013年5月5日在16:48
该时间段等效于“源”命令:tldp.org/LDP/abs/html/special-chars.html#DOTREF
–杰夫W
13年8月8日在21:55
@PeterLee提到的任何内容对您有用吗?我写这篇文章是因为上述解决方案对我而言无效。如果上述解决方案不起作用,我将必须进行一些研究以找出原因。 ;-)
– Vishal
13年3月22日在5:48
@Vishal实际上,它现在对我有用。我试图获取〜/ .bashrc的资源,结果发现我的.bashrc文件与cron作业有点冲突。如果我仅使用一行仅使用一个非常简单的.env_setup_rc文件:export MY_ENV_VAR = my_env_val,它实际上可以工作。看到我的帖子:stackoverflow.com/questions/15557777/…
– Peter Lee
13年3月22日在5:53
#4 楼
在/etc/environment
中设置vars在Ubuntu中也对我有用。从12.04开始,将为cron加载/etc/environment
中的变量。评论
最佳答案,只需执行env >> / etc / environment,现在CRON作业中就可以使用所有当前的env var。
–野蛮人
16 Mar 16 '16 at 12:39
这对我来说很棒。尤其是因为我遇到了Docker容器,因此我不太关心“系统范围”的含义。
–卢卡斯·波特斯基(Lucas Pottersky)
16年5月25日在13:31
@Savageman就像用融合炸弹杀死苍蝇一样,意外行为的风险也很高。
– Fran Marzoa
16年8月17日在9:41
注意:env >> / etc / environment将在环境变量之一中出现哈希符号时失败。我最难对应用程序进行故障排除。原来是一个包含“#”的密码,该密码在该步骤被截断。
–asachet
19-09-18在10:38
这应该是选择的答案。我不知道为什么人们将其他答案或与env >> / etc / environment有关的东西变得复杂。如果您希望这些环境变量可以普遍使用,请稍等一下编辑/环境,我的实验似乎证实了/ etc / environment中环境变量的导出语句对crontab以及用户都可用。问题:再次根据我的实验:看来这些环境变量在crontab本身中并未扩展! ...即仅在称为的脚本中对其进行扩展!
–麦克·啮齿动物
19-10-17在12:23
#5 楼
如果您通过以下命令通过cron执行脚本,请执行以下操作:#!/bin/bash -l
它们应该获取您的
~/.bash_profile
环境变量评论
这个答案应该得到更多的认可,并且应该只是被选择的答案:非常简单而优雅,避免了无数次需要在系统中跳转的麻烦。
–Giacomo1968
18/12/14在4:42
我喜欢这个答案+1。可以/应该在运行root的crontab时使用吗?我的系统上没有/ home / root文件夹,因此我看不到它将与root的crontab一起使用。有想法吗?
– Seamus
1月29日23:54
在脚本本身中。然后您通常使用cron运行该程序。
–breizhmg
4月25日晚上8:17
@Jim参见此示例,经典可执行文件(chmod 777)使用#!/ bin / bash。这里的魔术是添加-l
– Peter Krauss
5月6日2:24
这个人的解释:-l使bash就像被作为登录shell调用一样(请参阅下面的INVOCATION)。
–炒锅
11月19日12:10
#6 楼
扩展@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源文件之后的任何命令都将具有您登录后的环境。
#7 楼
对我来说,我必须为php应用程序设置环境变量。我通过在我的crontab中添加以下代码来喜欢它。$ sudo crontab -e
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
doSomethingWonderful.php我可以使用以下方法获取环境值:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
我希望这会有所帮助!
评论
这对我不起作用。环境变量在crontab内部调用的脚本中不可用。
–豪猪
19年6月26日在10:56
#8 楼
您在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
< br并说脚本
/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
...
#9 楼
在@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 楼
代替0 * * * * sh /my/script.sh
使用bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
评论
为什么这样做而不是仅在文件顶部使用Bash声明使-l像这样:#!/ bin / bash -l?这另一个答案是简单而优雅的。
–Giacomo1968
18/12/14在4:41
如果我需要运行Perl / python / ruby脚本而不是bash怎么办?我无法在Python脚本的顶部添加#!/ bin / bash -l。
–伊利亚·哈拉莫夫(Ilya Kharlamov)
18/12/14在14:58
“如果我需要运行perl / python / ruby脚本而不是bash怎么办?”很公平。但是在我看来,您可以编写一个简单的Bash脚本包装程序,然后调用Python脚本。我对PHP脚本也做类似的事情。原因是进程锁定在Bash中是更好和可靠的,但是Bash脚本编写仍然令人头疼。因此,我用PHP编写了一些复杂的内容,然后让Bash处理其余的内容。
–Giacomo1968
18/12/14在20:35
#11 楼
我在Macbook中使用Oh-my-zsh
,所以我尝试了很多事情来使crontab任务运行,但最终,我的解决方案是在运行命令之前添加.zshrc
。*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
此任务每30分钟运行一次,并使用
.zshrc
配置文件执行我的node命令。不要忘记在
$HOME
变量前使用点。#12 楼
您还可以在命令前加上env
来注入环境变量,如下所示:0 * * * * env VARIABLE=VALUE /usr/bin/mycommand
#13 楼
受此答案启发,另一种“注入”变量的方法如下(fcron示例):%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
从
help set
开始:-标记已修改或
使用+而不是-导致这些标志被关闭。
因此
set -
和set +
之间的所有内容都导出到env
,然后可用于其他脚本等。不使用set
,变量将被获取但仅存在于set
中。此外,当程序需要运行非root帐户但您需要在其他用户环境中使用一些变量时,传递变量也很有用。以下是传入nullmailer var来格式化电子邮件标题的示例:su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
#14 楼
我尝试了提供的大多数解决方案,但一开始没有任何效果。但事实证明,并非解决方案无法奏效。显然,我的~/.bashrc
文件以以下代码块开头:case $- in
*i*) ;;
*) return;;
esac
这基本上是一个
case statement
,它检查当前外壳程序中的当前选项集以确定shell正在以交互方式运行。如果shell恰好以交互方式运行,那么它将继续获取
~/.bashrc
文件。但是,在
cron
调用的shell中,$-
变量不包含i
表示交互性的值。因此,
~/.bashrc
文件从不完全获得源。因此,永远不会设置环境变量。如果这恰好是您的问题,请按照以下说明随意注释代码块,然后重试:
# case $- in
# *i*) ;;
# *) return;;
# esac
我希望这对您有帮助
#15 楼
对我来说,我必须在NodeJS文件中指定路径。 // did not work!!!!!
require('dotenv').config()
而不是
// DID WORK!!
require('dotenv').config({ path: '/full/custom/path/to/your/.env' })
#16 楼
不幸的是,crontabs的环境变量范围非常有限,因此每次corntab运行时都需要导出它们。下面的示例是一个简单的方法,假设您将env vars保存在一个名为env的文件中,然后:
* * * * * . ./env && /path/to_your/command
这部分
. ./env
将导出它们,然后在您命令的相同范围内使用它们#17 楼
全局设置环境
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"
=)
#18 楼
以上所有解决方案都可以正常工作。当环境变量中有任何特殊字符时,它将产生问题。
我找到了解决方案:
eval $(printenv | awk -F= '{print "export " "\"""\"""=""\"""\"" }' >> /etc/profile)
评论
请注意,您不能像在shell中那样使用变量替换,因此像PATH = / usr / local / bin:$ PATH这样的声明将按字面解释。
–扎克
13年5月5日在10:13
我能够在RedHat 4.4.7-3和cronie-1.4.4-15.el6.x86_64下的crontab自身中设置环境变量
–布鲁诺·兰格(Bruno Lange)
2015年6月9日在13:24
如果仅在命令中使用变量,则实际上不需要导出变量,只需在命令之前添加它们即可。 “ * * * * *睡眠5秒钟; LC_ALL = nb_NO.UTF-8 echo $ LC_ALL”
– vutran
15年11月13日在8:10
如@bruno所说,cronie现在确实从crontab中复制了除少数几个环境变量外的所有变量。
–mtd
19年2月2日,18:41
@BrunoLange,请您分享您如何设置它们?
–Newskooler
19年2月13日在16:35