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

编辑:(来自评论)我知道该命令在shell(我的shell)中输入时效果很好,但是我想知道在cron运行它时该命令是否正确运行,可能会受到以下影响ENV或Shell特定的内容(〜扩展)或所有权和权限的内容或...

评论

我知道命令在外壳程序(我的外壳程序)中输入时有效,但是我想知道cron运行它时是否有效,它可能会受到ENV或外壳程序特定内容(〜扩展)或所有权和权限内容或..的影响。 。

那么,为什么不创建使用相同命令每分钟运行一次的新cron作业呢?

这正是我最终要做的事情,但是我想知道是否有一种方法可以告诉cron您要对7号作业进行测试!当然其他人以前也有这个问题/要求/希望!

通过Google到达现场的时间很晚,但是关于favadi的回复有什么不对劲。很明显,他想从cron进行测试,而无需专门编辑crontab来进行测试。比没有告诉您您想要的东西时,他们还没有尝试理解用例的地方要小。

@Ali当您这样说时,我理解您的理由(严格来说,没有cron本机的方法可以使cron自己在即兴的时间运行任务)。 Vadim-Sluzky的答案在很多情况下都可能有用,但是对于那些真正难以确定的问题,Michael-Barton的答案更为合适。我想,如果您只是“取消选择”当前正确的一个,而没有“正式”正确的一个,那么仅凭投票就能使其他事情升至最高。

#1 楼

据我所知,由于cron具有特殊用途,因此无法直接执行此操作-在特定时间运行计划命令。因此,最好的办法是手动创建(临时)crontab条目,或者编写一个删除并重置环境的脚本。
解释“删除并重置环境”:
包装器脚本可以是从env -i(删除环境)开始,它将在启动脚本之前提供保存的环境(确保导出所有变量,可能首先通过设置set -a)。
保存的环境将是cron的默认环境作业,通过将env(或declare -p取决于cron作业使用的shell)运行作为cronjob记录下来,保存其输出。

#2 楼

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

run-parts /etc/cron.daily


评论


...假设OP的cron工作(要求3年)位于cron.daily,而不是单个crontab。

– Jeff Schaller♦
15年11月24日在3:49

但是,这并不能完全模拟cron用户的环境,因此很可能仍然有bug,因为一旦将脚本作为实际的cron作业运行,您的PATH和其他envvar可能与您运行部分的用户不同/etc/cron.daily as。我现在正在解决此错误,因为我的脚本可以在运行部件上正常运行,但是在cron用户下实际运行时会失败。

– ArtHare
17年6月14日15:41



我如何运行cron.d / localhost这是rsnspshot命令?

–布赖恩·托马斯(Brian Thomas)
20-09-11的2:20

在某些安装(例如Ubuntu)上,在sudo前缀命令很有帮助。

–WinEunuuchs2Unix
20-10-21在0:22

这不会在正确的环境中运行作业。另外,为什么要运行所有日常工作以仅测试运行一项工作?

– Kusalananda♦
20/12/26在22:24

#3 楼

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


摘录自链接:


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

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


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

步骤2:自己制作有点运行时的bash脚本,其中包含:

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



因此,作为有问题的用户,我能够

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


评论


有用的把戏。当然,如果您在命令中输入了百分号,那将无济于事。

–basic6
18年7月11日在7:09

确保在run-as-cron脚本的shebang行中放入cron使用的相同外壳。

–罗杰·柯林斯
20-04-23在15:50

#4 楼

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 ...


评论


非常感谢。这真是太好了!

– Xonshiz
20年1月6日在16:33

需要一些api键。每月49美元。

–ЯрославРахматуллин
20 Sep 4'9:42



#5 楼

如果有帮助,在需要自己调试cron作业之后,我编写了以下脚本。在运行脚本之前,它会尽力使其与cron处于完全相同的状态(该环境包括已修改的环境,但它也与非交互式shell,无附件,终端等有关)。

以命令/脚本作为参数调用它,您可以立即轻松地调试cron作业。
它也托管在Github上(并可能已更新)。

#!/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 "q4312078q - Run a script or a command as it would be in a cron job, then display its output"
    echo "Usage:"
    echo "   q4312078q [command | script]"
}

if [ "" == "-h" -o "" == "--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 route the output in a file
# and do not provide any input (so that the command is executed without an attached terminal)
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 3[1mstdout3[0m:"
cat "$so"
echo -e "Done. Here is 3[1mstderr3[0m:"
cat "$se"
rm "$so" "$se"


评论


这帮助我找到了问题。

–ЯрославРахматуллин
20年9月4日在10:34

“生成字符串”位是有问题的,将在env的帮助下以更安全的方式解决。

– Kusalananda♦
20/12/26在22:27

#6 楼

我发现一个解决方案似乎对我的目的更好(显示的命令适用于CentOS / RHEL,但基本上可以在任何地方适应)。

这需要libfaketime-您可以自己构建来源https://github.com/wolfcw/libfaketime或仅使用https://pkgs.org/download/libfaketime中的许多软件包之一。


停止crond服务- service crond stop

弄清楚服务的运行时间-https://crontab.guru对此非常有用。
通过libfaketime的faketime工具在前台模式下运行crond(它可以让您伪造出来)进行任何子进程的时间查找的系统调用。)


我不会在生产服务器上运行它
faketime '2019-10-17 07:59:50' /usr/sbin/crond -n -x test,sch



[root@user-crontesting-dvc-01 ~]# faketime '2019-10-17 07:59:50' /usr/sbin/crond -n -x sch
debug flags enabled: sch
[4841] cron started
log_it: (CRON 4841) INFO (Syslog will be used instead of sendmail.)
log_it: (CRON 4841) INFO (RANDOM_DELAY will be scaled with factor 34% if used.)
log_it: (CRON 4841) INFO (running with inotify support)
[4841] GMToff=0
log_it: (CRON 4841) INFO (@reboot jobs will be run at computer's startup.)
[4841] Target time=1571299200, sec-to-wait=11
user [root:0:0:...] cmd="/usr/libexec/myexc/crontesting.cron > /dev/null 2> &1"
[4841] Target time=1571299260, sec-to-wait=60
log_it: (root 4844) CMD (/usr/libexec/myexc/crontesting.cron > /dev/null 2> &1)
log_it: (root 4843) CMDOUT (/bin/bash: -c: line 0: syntax error near unexpected token `&')
log_it: (root 4843) CMDOUT (/bin/bash: -c: line 0: `/usr/libexec/myexc/crontesting.cron > /dev/null 2> &1')


#7 楼

我引用了serverfault的答案(完整查看):


批量执行crontab命令:

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


运行它在另一个用户下:

sudo -H -u username bash -c "crontab... "

#8 楼

达拉迪姆的回答对我很有用。它立即运行该命令,而不是像在“ * * * * *”样式回答中那样,最多在59秒后运行。它会在命令运行后立即显示输出。
我对其进行了扩展,增加了以任何用户身份运行的能力,而不仅仅是root用户,修复了一些极端情况的错误,并添加了带有引导信息的特定消息与cron匹配的环境。
我将其放在github上:https://github.com/poleguy/run-as-cron.git
将名为run-as-cron的命令链接到此文件
如果您有crontab条目,例如:
0 0 * * * command.sh --option
像这样测试它:
run-as-cron command.sh --option
或作为root用户:
sudo run-as-cron command.sh --option
或以其他用户身份使用:
sudo su otheruser
run-as-cron command.sh --option
请注意,第一次以用户身份运行此命令时,需要向crontab -e添加命令并等待一分钟来抓住环境。
这些问题和答案也可能有用:
https://stackoverflow.com/questions/4984725/test-a-weekly-cron-job
https ://serverfault.com/questions/85893/running-a-cron-job-manually-and-immediately

#9 楼

不是很优雅,但是可以正常工作:这是我在crontab的第5行启动工作的方式:

 eval "$(crontab -l | sed -n '5p' | tr -s ' ' | cut -d' ' -f 6-)"


它显示crontab,获得第5行,用一个空格替换多个空格,将所有内容从第6列移到末尾,然后使用eval启动它。

评论


这与剪切和粘贴命令相同,OP已声明该命令以其用户身份运行时有效。

–马丁
20年2月7日在15:40