我需要在 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'