如何模拟环境cron执行脚本?

我通常有几个问题,如何执行脚本,因为他们通常没有我的环境设置。 有没有办法像cron那样调用bash(?),以便在安装之前testing脚本?

将此添加到您的cron:

30 08 * * * env > ~/cronenv 

运行后,执行以下操作:

 env - `cat ~/cronenv` /bin/sh 

这假设你的cron运行/ bin / sh,这是默认的shell,不pipe用户的默认shell。

Cron默认只提供这种环境:

  • HOME用户的主目录
  • LOGNAME用户的login
  • PATH=/usr/bin:/usr/sbin
  • SHELL=/usr/bin/sh

如果您需要更多,可以在crontab中的调度表之前定义您的环境。

几种方法:

  1. 导出cron env并源代码:

     * * * * * env > ~/cronenv 

    到你的crontab,让它运行一次,把它关掉,然后运行

     env - `cat ~/cronenv` /bin/sh 

    你现在正在一个有cron环境的会议里面

  2. 把你的环境带到cron

    你可以跳过上面的练习,只是做一个. ~/.profile . ~/.profile在你的cron作业前,例如

     * * * * * . ~/.profile; your_command 
  3. 使用屏幕

    以上两种解决scheme仍然失败,因为它们提供了连接到正在运行的X会话的环境,并访问了dbus等。例如,在Ubuntu上, nmcli (networkingpipe理器)将以上述两种方式工作,但在cron中仍然失败。

     * * * * * /usr/bin/screen -dm 

    将上面的行添加到cron,让它运行一次,把它关掉。 连接到你的屏幕会话(屏幕-r)。 如果你正在检查已经创build的屏幕会话(使用ps ),请注意它们有时以大写字母(例如ps | grep SCREEN

    现在即使nmcli和类似的也会失败。

你可以运行:

 env - your_command arguments 

这将在空的环境下运行your_command。

取决于帐户的shell

 sudo su env -i /bin/sh 

要么

 sudo su env -i /bin/bash --noprofile --norc 

http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html

创build运行env并将stdoutredirect到文件的cron作业。 将该文件与“env – ”一起使用以创build与cron作业相同的环境。

六年后回答:环境不匹配问题是由systemd “定时器”解决的问题之一。 无论是从CLI还是通过cron运行systemd“服务”,它都能得到完全相同的环境,避免了环境不匹配的问题。

导致cron作业手动传递失败的最常见问题是由cron设置的限制性默认$PATH ,这在Ubuntu 16.04上是这样的:

 "/usr/bin:/bin" 

相比之下,Ubuntu 16.04上由systemd设置的默认$PATH是:

 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 

所以有一个更好的机会,一个systemd定时器将会find一个二进制文件没有进一步的麻烦。

系统定时器的缺点是,有一点时间来设置它们。 你首先创build一个“服务”文件来定义你想运行什么,一个“定时器”文件来定义运行时间表,最后“启用”定时器来激活它。

不要忘记,因为cron的父母是初始化,它运行没有控制terminal的程序。 你可以用这样的工具来模拟:

http://libslack.org/daemon/

默认情况下, cron使用sh系统来执行它的任务。 这可能是实际的Bourne shell或dashashkshbash (或另一个)符号链接到sh (并作为结果在POSIX模式下运行)。

要做的最好的事情是确保你的脚本有他们需要的东西,并假定什么都没有提供给他们。 因此,您应该使用完整的目录规范并自行设置环境variables(如$PATH

我发现的另一个简单的方法(但可能容易出错,我还在testing)是在您的命令之前获取用户的configuration文件。

编辑/etc/cron.d/脚本:

 * * * * * user1 comand-that-needs-env-vars 

会变成:

 * * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars 

脏,但它为我完成了工作。 有没有办法模拟login? 只是一个命令,你可以运行? bash --login没有工作。 这听起来似乎是更好的方式去。

编辑:这似乎是一个坚实的解决scheme: http : //www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/

 * * * * * root su --session-command="comand-that-needs-env-vars" user1 -l 

回答https://stackoverflow.com/a/2546509/5593430显示如何获取cron环境并将其用于您的脚本。; 但请注意,根据您使用的crontab文件,环境可能会有所不同。 我创build了三个不同的cron条目来通过env > log保存环境。 这些是Amazon Linux 4.4.35-33.55.amzn1.x86_64上的结果。

1.具有root用户的全局/ etc / crontab

 MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=1 HOME=/ LOGNAME=root _=/bin/env 

2. root用户crontab( crontab -e

 SHELL=/bin/sh USER=root PATH=/usr/bin:/bin PWD=/root LANG=en_US.UTF-8 SHLVL=1 HOME=/root LOGNAME=root _=/usr/bin/env 

3. /etc/cron.hourly/中的脚本

 MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin _=/bin/env PWD=/ LANG=en_US.UTF-8 SHLVL=3 HOME=/ LOGNAME=root 

最重要的是PATHPWDHOME不同。 确保在cron脚本中设置这些脚本来保证稳定的环境。

我不相信有; 我知道testing一个cron工作的唯一方法就是将其设置为将来运行一两分钟,然后等待。