在cronjob中加载用户环境variables

我如何加载用户环境variablescronjob?


我有一个应该在Ubuntu机器上每分钟启动一个脚本的cronjob:

* * * * * /home/user/myscript.sh; 

在这个脚本中,我想使用像$JAVA_HOME$M2_HOME这样的环境variables来自动启动一个构build过程。 问题是这些variables是通过export JAVA_HOME=/../...bashrc中设置的。

因此,在执行我的脚本之前,我会提供这些文件:

 * * * * * source ~/.bash_profile; source ~/.bashrc; /home/user/myscript.sh; 

但是,variables没有设置! 为了testing这个,我通过env将环境variablesecho显到日志文件中:

 env >> ~/env.log echo $M2_HOME >> ~/env.log 

日志文件仍然不包含variables。 只有以下内容被追加到文件(无$M2_HOME等):

 LANGUAGE=en_US:en HOME=/home/user LOGNAME=user PATH=/usr/bin:/bin LANG=en_US.UTF-8 SHELL=/bin/sh PWD=/home/user 

如果我在shell中运行脚本,所有的variables都会打印到env.log

当我将source放入脚本文件时,情况也是如此。 只有在声明variables之前删除了export关键字,它才能被echo $var命令看到。 但这不是一个解决scheme,因为我不pipe理这些声明。


我尝试了@tripplee与有限的SH壳问题的解决scheme,但它仍然无法正常工作。 我进一步减less到一个非常简单的cronjob没有第二个脚本来显示问题:

 * * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log; 

cat /home/user/env.log

 LANGUAGE=en_US:en HOME=/home/user LOGNAME=user PATH=/usr/bin:/bin LANG=en_US.UTF-8 SHELL=/bin/sh PWD=/home/user 

cron作业语法仅限于sh所以不能使用〜〜等Bashisms。 幸运的是,修复很简单 – 只需用$HOMEreplace即可。 同样, source需要被replace. (只是一个点)。

当然,如果您打算从sh使用它们,则源代码的脚本不能使用Bash语法。 可能最简单的方法就是将这些东西迁移到脚本中(或者为Cron创build一个包装脚本来运行)。

因为在你的脚本里面,你可以使用bash如果你喜欢,当然提供的是shebang行是正确的#!/bin/bash (如果你必须调整path)而不是#!/bin/sh

如果因为某种原因不喜欢这种情况,可以通过明确地指定它来在你的crontab文件中embeddedBash:

 * * * * * bash -c 'source ~/.bash_profile; source ~/.bashrc; ./myscript.sh' 

你应该可以看到source: command not foundexport: command not foundcron发送的邮件中export: command not found 。 检查错误输出对于故障排除非常重要。

当然,如果你在Ubuntu上有标准的.bashrc ,如果你试图从一个非交互式脚本中获取它,它将立即释放。 也许更好然后把你想要的设置在一个非交互的使用在另一个文件(也许.profile默认sh将被读取)?

要添加到tripleee的答案,可以通过在crontab中指定shell来使bash(或您select的shell)对所有cron进行评估。

 SHELL=/bin/bash * * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log; 

编辑 ,如果你真的想看看它在做什么,下面的命令应该使它足够冗长:

 /bin/bash -x -c '. $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log' > /tmp/cron.`date +\%s` 

在命令行上set -x或-x标志将导致大部分shell打印每一行评估。

要在命令行上testing,请从date命令中删除\。 这是防止cron评估%s作为标准input所必需的。

你在cron中没有完整的tty 。 但是,如果你通过sudo -i运行它,你会得到一个。

 * * * * * sudo -u user -i bash -c '. $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;' 

或者启动脚本:

 * * * * * sudo -u user -i bash -c '. $HOME/.bash_profile; . $HOME/.bashrc; /home/user/myscript.sh;' 

如果你把source放在一个启动目标脚本的Bash脚本中,你会得到一个整洁的:

 * * * * * sudo -u user -i /home/user/mystarter.sh;