我怎样才能让 cron 现在运行一项工作,以进行测试/调试?不改变时间表!

Ali*_*Ali 247 cron debugging

我有一个计划每天运行的 cron 作业,除了更改计划之外,还有没有其他方法可以立即对命令进行测试运行以查看它是否按预期工作?

编辑:(从评论中)我知道在 shell(我的 shell)中输入命令时该命令可以正常工作,但是我想知道当 cron 运行它时它是否可以正常工作,它可能会受到 ENV 或特定于 shell 的东西的影响(~扩展) 或所有权和许可的东西或...

小智 111

您可以使用以下命令强制 crontab 运行:

run-parts /etc/cron.daily
Run Code Online (Sandbox Code Playgroud)

  • 但是,这并不能完全模拟 cron 用户的环境,因此您很可能仍然会遇到错误,因为一旦您将脚本作为实际的 cron 作业运行,您的 PATH 和其他环境变量可能与您运行的用户不同部分 /etc/cron.daily` 作为。我现在正在与这个错误作斗争,因为我的脚本可以在 `run-parts` 下正常运行,但在 cron 用户下实际运行时会失败。 (41认同)
  • ...假设 OP 的 cron 工作(3 年前询问)在 cron.daily 中,而不是单个 crontab。 (17认同)
  • 这不会在正确的环境中运行作业。另外,为什么您要运行所有日常作业只是为了测试运行单个作业? (3认同)

小智 83

您可以按照“立即手动运行 cron 作业”中的说明模拟 cron 用户环境。这将允许您在以 cron 用户身份运行时测试作业是否有效。


摘自链接:


第 1 步:我将此行临时放在用户的 crontab 中:

* * * * *   /usr/bin/env > /home/username/tmp/cron-env
Run Code Online (Sandbox Code Playgroud)

然后在写入文件后将其取出。

第 2 步:让我自己做一个小的 run-as-cron bash 脚本,其中包含:

#!/bin/bash
/usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@"
Run Code Online (Sandbox Code Playgroud)

那么,作为有问题的用户,我能够

run-as-cron /the/problematic/script --with arguments --and parameters
Run Code Online (Sandbox Code Playgroud)


Ulr*_*gel 41

据我所知,没有办法直接做到这一点,因为 cron 有一个特殊的目的——在特定时间运行调度命令。所以最好的办法是手动创建一个(临时的)crontab 条目或编写一个删除和重置环境的脚本。

“移除并重置环境”的解释:

可以使用包装器脚本env -i(删除环境)开始,这将set -a在启动脚本之前提供保存的环境(确保导出所有变量,可能通过首先设置)。

保存的环境将是 cron 作业的默认环境,通过运行env(或declare -p取决于您的 cron 作业使用的 shell)作为 cronjob 进行记录,保存其输出。


小智 11

CronitorCLI 有一个命令cronitor select,可让您从命令行选择和运行任何 cron 作业。您无需创建 Cronitor 帐户即可使用它。

https://cronitor.io/docs/using-cronitor-cli

下面是一个例子:

ubuntu@ip-10-0-0-112:~$ cronitor select

Use the arrow keys to navigate: ? ?
? Select job to run:
? /var/runner/src/bin/batch_reports.py runner.settings.prod
  /var/runner/src/bin/trigger_reports.py runner.settings.prod
  ... etc ...
Run Code Online (Sandbox Code Playgroud)

  • 需要一些 api 密钥。每月 49 美元。 (4认同)
  • @ЯрославРахматуллин,您可以在 CronitorCLI 安装过程中省略该步骤(`sudo cronitor configure --api-key <API-KEY>`),并且 `cronitor select` 仍然有效。 (2认同)

小智 7

在需要自己调试 cron 作业后,\n我\xc2\xa0 编写了以下脚本。\xc2\xa0\n它\xc2\xa0\n在运行\xc2\xa0 命令(包括修改过的环境,\n但它也与非交互式 shell、\n没有连接的终端等有关)。

\n

使用您的命令/脚本作为参数调用它,您可以立即轻松地调试您的 cron 作业。\n它也托管(并可能更新)在 GitHub 上run-as-cron.sh::

\n
#!/bin/bash\n# Run as if it was called from cron, that is to say:\n#  * with a modified environment\n#  * with a specific shell, which may or may not be bash\n#  * without an attached input terminal\n#  * in a non-interactive shell\n\nfunction usage(){\n    echo "$0 - Run a script or a command as it would be in a cron job," \\\n                                                       "then display its output"\n    echo "Usage:"\n    echo "   $0 [command | script]"\n}\n\nif [ "$1" == "-h" -o "$1" == "--help" ]; then\n    usage\n    exit 0\nfi\n\nif [ $(whoami) != "root" ]; then\n    echo "Only root is supported at the moment"\n    exit 1\nfi\n\n# This file should contain the cron environment.\ncron_env="/root/cron-env"\nif [ ! -f "$cron_env" ]; then\n    echo "Unable to find $cron_env"\n    echo "To generate it, run \\"/usr/bin/env > /root/cron-env\\" as a cron job"\n    exit 0\nfi\n\n# It will be a nightmare to expand "$@" inside a shell -c argument.\n# Let\'s rather generate a string where we manually expand-and-quote the arguments\nenv_string="/usr/bin/env -i "\nfor envi in $(cat "$cron_env"); do\n   env_string="${env_string} $envi "\ndone\n\ncmd_string=""\nfor arg in "$@"; do\n    cmd_string="${cmd_string} \\"${arg}\\" "\ndone\n\n# Which shell should we use?\nthe_shell=$(grep -E "^SHELL=" /root/cron-env | sed \'s/SHELL=//\')\necho "Running with $the_shell the following command: $cmd_string"\n\n\n# Let\'s redirect the output into files\n# and provide /dev/null as input\n# (so that the command is executed without an open terminal\n# on any standard file descriptor)\nso=$(mktemp "/tmp/fakecron.out.XXXX")\nse=$(mktemp "/tmp/fakecron.err.XXXX")\n"$the_shell" -c "$env_string $cmd_string" > "$so" 2> "$se"  < /dev/null\n\necho -e "Done. Here is \\033[1mstdout\\033[0m:"\ncat "$so"\necho -e "Done. Here is \\033[1mstderr\\033[0m:"\ncat "$se"\nrm "$so" "$se"\n
Run Code Online (Sandbox Code Playgroud)\n


pol*_*guy 5

达拉迪姆的回答对我很有用。它会立即运行命令,而不是像 " * * * * *" 风格的答案那样在最多 59 秒后运行。一旦命令运行,它就会显示输出。

我对它进行了一些扩展,增加了以任何用户身份运行的能力,而不仅仅是 root,修复了一些极端情况下的错误,并添加了一条特定的消息,其中包含引导环境以匹配 cron 的说明。

我把它放在 GitHub 上

将名为 run-as-cron 的命令从您的路径链接到此文件。

如果您有这样的 crontab 条目:

0 0 * * * command.sh --option
Run Code Online (Sandbox Code Playgroud)

像这样测试它:

run-as-cron command.sh --option
Run Code Online (Sandbox Code Playgroud)

或作为根:

sudo run-as-cron command.sh --option
Run Code Online (Sandbox Code Playgroud)

或作为其他用户:

sudo su otheruser
run-as-cron command.sh --option
Run Code Online (Sandbox Code Playgroud)

请注意,第一次以用户身份运行此程序时,您需要向其中添加命令crontab -e并等待一分钟以获取环境。

这些问题和答案也可能有用: