Answers:
在运行命令之前,让'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
“每日”命令比较简单:
: "@(#)$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
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
。
source ~/.bashrc
,结果证明我的.bashrc
文件与cron作业有点冲突。如果我使用一个.env_setup_rc
只有一行的非常简单的文件:export MY_ENV_VAR=my_env_val
,它实际上可以工作。请参阅我的文章:stackoverflow.com/questions/15557777/...
/etc/environment
在Ubuntu中设置vars 也对我有用。从12.04开始,/etc/environment
将为cron加载in 中的变量。
env >> /etc/environment
并且CRON作业中现在可以使用所有当前的环境变量。
env >> /etc/environment
如果环境变量之一中有哈希符号,则将失败。我最难对应用程序进行故障排除。原来是一个包含“#”的密码,该密码在该步骤被截断。
对我来说,我必须为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
...
在@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
代替
0 * * * * sh /my/script.sh
使用bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
受此答案启发,另一种“注入”变量的方法如下(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 var来格式化电子邮件头的示例:
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
我希望这对您有用