手动运行 cron 作业/模拟运行 cron 作业?

手动运行 cron 作业/模拟运行 cron 作业?

我想测试 cron 在执行任务之后的邮件发送以及类似的事情是否有效。有没有更优雅的方法来测试这个,然后设置一个 cron 作业每隔几秒运行一次?那么,有没有什么方法可以模拟 cron 作业的执行/手动启动 cron 作业,但具有与 cron 自动运行时相同的行为?

答案1

在命令行上执行 cron 作业和在 cron 内部执行 cron 作业的主要区别在于其环境。其他潜在的差异包括当前目录、终端的可用性以及使用的 shell。

这是通过 cron 运行 cron 作业的相当准确的模拟。为了避免由于 shell 造成的差异,请将您的作业放入脚本中,并仅将该脚本的路径放入 crontab 中。请注意,由 cron 传递的环境变量的确切设置和值取决于实现;检查crontab(5)系统上的手册页。ifne是一个命令,如果收到一些输入,则运行参数中指定的命令;有一个在更多实用程序

env -i HOME="$HOME" LOGNAME="$LOGNAME" PATH=/usr/bin:/bin SHELL=/bin/sh USER="$USER" \
    /path/to/script </dev/null 2>&1 |
ifne mail -r "Cron Daemon" -s "Cron <$USER@$(hostname)> /path/to/script" "$USER"

创建类似 cron 设置的另一种方法是通过at。但at负责使用at进程收到的环境变量运行命令,因此您仍然需要模拟这部分。

echo /path/to/script |
env -i HOME="$HOME" LOGNAME="$LOGNAME" PATH=/usr/bin:/bin SHELL=/bin/sh USER="$USER" \
    at now

答案2

以下是我如何模拟我几年前创建的脚本的 cron 执行,但该脚本最近开始失败。

我创建了一个名为的脚本dumpenv

#!/bin/sh

base=$(basename $0)

env -0 > /tmp/$base.$$.dump

这会将所有环境变量转储到/tmp/.然后我修改了我的 crontab 添加:

*/1 * * * *  [path to newly created script]

这使得脚本每分钟运行一次。一分钟后,我得到了从 cron 运行的任务所看到的环境转储。如果 crontab 行运行超过一分钟,它会创建一堆相同的文件,其名称仅在文件名的 pid 部分有所不同 ( $$)。没什么大不了的。我可以针对这种可能性进行编码,以便只获取一个文件,但这里的主要原则是“足够好”,并且我可能想dumpenv在多个转储有用的其他上下文中使用。无论如何,建议删除添加的 crontab 行,以避免填充/tmp大量垃圾。

然后我创建了一个额外的文件,我称之为/tmp/command其中包含我想要执行的命令,在一行上以空字符终止。空字符是必需的。

然后我发出:

cat [path to dumpfile crated earlier] /tmp/command | xargs -0 -x env -i

这复制了我从 cron 执行命令时看到的错误。所做xargs的是构建以下形式的命令:

env -i [list of environment variables] [command to execute]

并执行它。环境变量列表来自转储文件。执行的命令env来自/tmp/command文件。

我上面提到的and-0的参数以及所需的空字符是为了防止在传递变量时发生环境破坏。如果环境不包含带有换行符的环境变量,则可以从脚本和命令的调用中省略,并且文件不需要空字符作为行终止符。envxargs-0envdumpenvxargs/tmp/command

我没有将 stdin 显式重定向到 /dev/null 因为 xargs 为我做了它。我也不关心重定向 stdout/stderr,并且我不想在命令失败时收到电子邮件。对于需要这些功能的情况,吉尔斯的答案提供了实现它的方法。

答案3

路易斯的回答是很棒的。我提出了一些可能的改进。

/tmp/command不要像 Louis 在以下代码中建议的那样创建包含要执行的脚本路径的文件:

cat [path to dumpfile crated earlier] /tmp/command | xargs -0 -x env -i

相反,您可以通过以下备用命令直接在命令中命名脚本(请注意\x00附加到 cron 脚本路径,这是必不可少的:

printf "/path/to/cron/script\x00" | cat /path/to/dumpfile/created/earlier - | xargs -0 -x env -i

这避免了创建文件的需要/tmp/command

相关内容