立即手动运行 cron 任务

立即手动运行 cron 任务

(我已经读过我如何测试新的 cron 脚本?

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

答案1

这是我所做的,它似乎在这种情况下有效。至少,它向我显示了一个错误,而以用户身份从命令行运行不会显示错误。


步骤1:我把这一行暂时放在用户的crontab中:

* * * * *   /usr/bin/env > /home/username/tmp/cron-env

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

第2步:自己制作了一个小型的 cron 运行 bash 脚本,其中包含:

#!/bin/bash
/usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@"

因此,作为相关用户,我能够

run-as-cron /the/problematic/script --with arguments --and parameters

显然,这个解决方案可以扩展以利用 sudo 或类似技术来获得更大的灵活性。

希望这对其他人有帮助。

答案2

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

  • 将以下行添加到 crontab,例如使用crontab -e

    * * * * *  /usr/bin/env > /home/username/cron-env
    
  • 创建一个 shell 脚本,在与 cron 作业运行相同的环境中执行命令:

    #!/bin/sh
    
    . "$1"
    exec /usr/bin/env -i "$SHELL" -c ". $1; $2"
    

使用:

run-as-cron <cron-environment> <command>

例如

run-as-cron /home/username/cron-env 'echo $PATH'

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

答案3

由于 crontab 不执行该工作,您将操纵其内容:

crontab -l | grep -v '^#' | cut -f 6- -d ' ' | while read CMD; do eval $CMD; done

它能做什么 :

  • 列出 crontab 任务
  • 删除注释行
  • 删除 crontab 配置
  • 然后逐个启动它们

答案4

由于某种原因,Marco 的脚本对我来说不起作用。我没有时间调试,所以我编写了一个 Python 脚本来执行相同的操作。它更长,但:首先,它对我来说是有效的,其次,我发现它更容易理解。将“/tmp/cron-env”更改为您保存环境的位置。它在这里:

#!/usr/bin/env python
from __future__ import division, print_function

import sys
import os

def main():
    if len(sys.argv) != 2 or sys.argv[1] in ('-h', '--help'):
        print("Usage: {} CMD\n"
              "Run a command as cron would. Note that CMD must be quoted to be only one argument."
              .format(sys.argv[0]))
        sys.exit(1)
    _me, cmd = sys.argv
    env = dict(line.strip().split('=', 1) for line in open('/tmp/cron-env'))
    sh = env['SHELL']
    os.execvpe(sh, [sh, '-c', cmd], env)

if __name__ == '__main__':
    main()

相关内容