我怎样才能让 cron 立即运行一个作业来进行测试/调试?不改变日程!

我怎样才能让 cron 立即运行一个作业来进行测试/调试?不改变日程!

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

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

答案1

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

run-parts /etc/cron.daily

答案2

您可以模拟 cron 用户环境,如中所述“立即手动运行 cron 作业”。这将允许您测试作业以 cron 用户身份运行时的工作情况。


摘自链接:


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

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

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

第2步:自己制作了一个 run-as-cron bash 脚本,其中包含:

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

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

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

答案3

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

“删除并重置环境”的说明:

可以启动包装器脚本(这会删除环境),该脚本将在启动脚本之前env -i获取已保存的环境(确保导出所有变量,可能首先进行设置)。set -a

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

答案4

在需要自己调试 cron 作业后,我编写了以下脚本。在运行命令之前,它会尽力模拟与 cron 完全相同的条件(包括修改的环境,但它也与非交互式 shell、无附加终端等有关)。

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

#!/bin/bash
# Run as if it was called from cron, that is to say:
#  * with a modified environment
#  * with a specific shell, which may or may not be bash
#  * without an attached input terminal
#  * in a non-interactive shell

function usage(){
    echo "$0 - Run a script or a command as it would be in a cron job," \
                                                       "then display its output"
    echo "Usage:"
    echo "   $0 [command | script]"
}

if [ "$1" == "-h" -o "$1" == "--help" ]; then
    usage
    exit 0
fi

if [ $(whoami) != "root" ]; then
    echo "Only root is supported at the moment"
    exit 1
fi

# This file should contain the cron environment.
cron_env="/root/cron-env"
if [ ! -f "$cron_env" ]; then
    echo "Unable to find $cron_env"
    echo "To generate it, run \"/usr/bin/env > /root/cron-env\" as a cron job"
    exit 0
fi

# It will be a nightmare to expand "$@" inside a shell -c argument.
# Let's rather generate a string where we manually expand-and-quote the arguments
env_string="/usr/bin/env -i "
for envi in $(cat "$cron_env"); do
   env_string="${env_string} $envi "
done

cmd_string=""
for arg in "$@"; do
    cmd_string="${cmd_string} \"${arg}\" "
done

# Which shell should we use?
the_shell=$(grep -E "^SHELL=" /root/cron-env | sed 's/SHELL=//')
echo "Running with $the_shell the following command: $cmd_string"


# Let's redirect the output into files
# and provide /dev/null as input
# (so that the command is executed without an open terminal
# on any standard file descriptor)
so=$(mktemp "/tmp/fakecron.out.XXXX")
se=$(mktemp "/tmp/fakecron.err.XXXX")
"$the_shell" -c "$env_string $cmd_string" > "$so" 2> "$se"  < /dev/null

echo -e "Done. Here is \033[1mstdout\033[0m:"
cat "$so"
echo -e "Done. Here is \033[1mstderr\033[0m:"
cat "$se"
rm "$so" "$se"

相关内容