如何模拟环境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中的调度表之前定义您的环境。
几种方法:
-
导出cron env并源代码:
加
* * * * * env > ~/cronenv
到你的crontab,让它运行一次,把它关掉,然后运行
env - `cat ~/cronenv` /bin/sh
你现在正在一个有cron环境的会议里面
-
把你的环境带到cron
你可以跳过上面的练习,只是做一个
. ~/.profile
. ~/.profile
在你的cron作业前,例如* * * * * . ~/.profile; your_command
-
使用屏幕
以上两种解决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的程序。 你可以用这样的工具来模拟:
默认情况下, cron
使用sh
系统来执行它的任务。 这可能是实际的Bourne shell或dash
, ash
, ksh
或bash
(或另一个)符号链接到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
最重要的是PATH
, PWD
和HOME
不同。 确保在cron脚本中设置这些脚本来保证稳定的环境。
我不相信有; 我知道testing一个cron工作的唯一方法就是将其设置为将来运行一两分钟,然后等待。