立即手动运行 cron 作业

Pis*_*tos 134 cron

(我已经阅读了如何测试新的 cron 脚本?。)

我有一个特定的问题(cron 作业似乎没有运行或正常运行),但问题很普遍:我想调试 cronned 的脚本。我知道我可以设置 * * * * * crontab 行,但这不是一个完全令人满意的解决方案。我希望能够从命令行运行 cron 作业,就像 cron 正在运行它一样(相同的用户、相同的环境变量等)。有没有办法做到这一点?必须等待 60 秒来测试脚本更改是不切实际的。

Pis*_*tos 98

这就是我所做的,它似乎在这种情况下有效。至少,它向我显示了一个错误,而作为用户从命令行运行时却没有显示错误。


第 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)

显然可以扩展此解决方案以使用 sudo 等以获得更大的灵活性。

希望这对其他人有帮助。

  • 这对我不起作用,我想知道它是否适用于任何投票的人。1)你为什么使用bash?这里不需要它,它可能不在`/usr/bin`中。2) `cat .../cron-env` 输出多行,这是行不通的。只需尝试在终端中执行 `/usr/bin/env -i $(cat cron-env) echo $PATH`,它会逐字输出环境而不是使用它。3)当前环境泄漏到模拟的cron环境中。尝试:`export foo=leaked; run-as-cron echo $foo`。 (8认同)
  • @Marco 2. `cat` 输出多行,它们确实有效,因为 shell 替换将它们折叠成一行,您可以使用 `echo $(cat cron-env ) | 检查它。wc`; 您的示例命令`/usr/bin/env -i $(cat cron-env) echo $PATH`,从调用shell 替换`$PATH`;相反,它应该调用一个子shell来替换子环境,例如`/usr/bin/env -i $(cat cron-env) /bin/sh -c 'echo $PATH'`。3. 你犯了同样的错误,再次在调用 shell 中替换而不是在子环境中 (7认同)

Mar*_*rco 48

我提出了一个基于 Pistos 答案的解决方案,但没有缺陷。

用:

run-as-cron <cron-environment> <command>
Run Code Online (Sandbox Code Playgroud)

例如

run-as-cron /home/username/cron-env 'echo $PATH'
Run Code Online (Sandbox Code Playgroud)

请注意,如果需要参数,则需要引用第二个参数。脚本的第一行加载一个 POSIX shell 作为解释器。第二行是 cron 环境文件的来源。这是加载正确的 shell 所必需的,它存储在环境变量中SHELL。然后它加载一个空环境(以防止环境变量泄漏到新 shell 中),启动用于 cronjob 的相同 shell 并加载 cron 环境变量。最后执行命令。


Dja*_*nny 24

由于 crontab 不做这项工作,你将操纵它的内容:

crontab -l | grep -v '^#' | cut -f 6- -d ' ' | while read CMD; do eval $CMD; done
Run Code Online (Sandbox Code Playgroud)

它能做什么 :

  • 列出 crontab 作业
  • 删除注释行
  • 删除 crontab 配置
  • 然后一一启动

  • 仍然是一个很棒的解决方案+1 (6认同)
  • 但是,这不一定在与 cron 相同的环境中进行,而且我认为他只想测试其中一个。 (5认同)
  • 正确,我弄错了……它只运行作业,但不像 cron 那样! (2认同)
  • 你可以`sudo -H -u otheruser bash -c 'crontab..." ` 来运行另一个用户的crontab btw (2认同)

Phi*_*lds 6

默认情况下,我见过的大多数默认 cron 守护程序,根本无法告诉 cron 现在就在这里运行。如果您使用 anacron,我认为有可能在前台运行一个单独的实例。

如果您的脚本运行不正常,那么您就没有考虑到这一点

  • 脚本以特定用户身份运行
  • cron 环境受限(最明显的表现就是路径不同)。

来自 crontab(5):

cron(8) 守护进程会自动设置几个环境变量。SHELL 设置为 /bin/sh,LOGNAME 和 HOME 是从 crontab 所有者的 /etc/passwd 行设置的。PATH 设置为“/usr/bin:/bin”。HOME、SHELL 和 PATH 可能会被 crontab 中的设置覆盖;LOGNAME 是运行作业的用户,不能更改。

一般来说 PATH 是最大的问题,所以你需要:

  • 在测试时,将脚本中的 PATH 显式设置为 /usr/bin:/bin。您可以在 bash 中使用export PATH="/usr/bin:/bin" 执行此操作
  • 在 crontab 的顶部显式设置您想要的正确 PATH。例如 PATH="/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin"

如果您需要在没有 shell 的情况下以其他用户身份运行脚本(例如 www-data),请使用 sudo:

sudo -u www-data /path/to/crontab-script.sh
Run Code Online (Sandbox Code Playgroud)

当然,在所有这些之前要测试的第一件事是您的脚本实际上执行了它应该从命令行执行的操作。如果你不能从命令行运行它,它显然不能与 cron 一起工作。