用于 crontab 验证的正则表达式

用于 crontab 验证的正则表达式

我需要在 bash 中检查 crontab 文件中的条目是否有效。有crontab命令开关吗?

我可以提取单独的行并尝试通过正则表达式控制单独的项目,但我不知道如何检查记录的类型,例如10,20,30,,*/2-Jan-May,Dec关于如何执行此操作的任何建议?

read -a cron <<< "${cron_tab}"  
if [[ "${cron[0]}" =~ ^(@(reboot|yearly|annualy|monthly|weekly|daily|hourly))$ ]]; then
        ...

    #check minutes
    if [[ "${cron[0]}" =~ ^([*]|[0-5][0-9]{1})$ ]]; then
        ...
    #check hours
    if [[ "${cron[1]}" =~ ^([*]|[01]?[0-9]|2[0-3])$ ]]; then
    ...
    #check days
    if [[ "${cron[2]}" =~ ^([*]|[0-2]?[0-9]|3[0-1])$ ]]; then
        ...         
    #check months
    if [[ "${cron[3]}" =~ ^([*]|[0]?[0-9]|1[0-2])$ ]]; then
    ...
    #check days of week
    if [[ "${cron[4]}" =~ ^([*]|[0]?[0-7])$ ]]; then
    ...

答案1

测试 crontab 行是否有效的最可靠方法是询问crontab实用程序。

大多数crontab实用程序没有只验证而不更改 crontab 的选项。您可以调用crontab -e设置 crontab,如果成功,则恢复以前的内容,但这并不可靠:如果输入有效,则在恢复之前时钟恰好经过一分钟,则可以启动其中包含的作业。之前的内容,如果其他人同时修改了 crontab,一个或两个操作都会被中断。

所以你能做的就是调用crontab它自己的游乐场。执行此操作的一种方法是在chroot— 真货还是假货。您可以致电假根创建一个假的 chroot 环境而不是 root。以下是从空目录开始填充它的方法:

mkdir -p bin etc tmp var/spool/cron/crontabs
echo "temp:x:$(id -u):65534:Temporary user:/:/none" >etc/password
touch var/spool/cron/crontabs
cp /usr/bin/crontab /bin/sh /bin/sleep /bin/cat bin/
cat "${cron_tab}" >input

echo n | env -i EDITOR='sleep 1; cat /input >' fakechroot -d /lib/ld-linux.so.2 -- chroot . /bin/crontab -e

根据您的系统调整可执行文件的位置。/lib/ld-linux.so.2是动态加载器;我给出了适用于 x86_32 上的 Linux 的位置,适用/lib64/ld-linux-x86-64.so.2于 x86_64 上的 Linux 的位置,等等。您可以通过运行ldd /bin/cat并记下给出的单个绝对路径来找到该位置。

如果 crontab 有效(它也会修改var/spool/cron/crontabs/temp),最后一个命令将返回 0。如果 crontab 无效,它会返回错误状态并打印错误消息。

sleep 1确保crontab不会认为文件没有更改(某些实现会检查修改时间,而某些文件系统的文件时间戳只有 1 秒的粒度)。为了避免延迟,您可以复制该touch实用程序而不是sleep,并安排通过设置更改时间戳(如果您有 GNU touch

EDITOR='f () { cat /input >"$1"; touch -d "+ 1 second" }; f'

相关内容