用于 crontab 验证的正则表达式

Vsw*_*Vsw 4 bash cron shell-script regular-expression

我需要在 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
    ...
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 5

The most reliable way to test whether a crontab line is valid is to ask the crontab utility.

Most crontab utilities don't have an option to only validate and not change the crontab. You can call crontab -e to set the crontab, and if this succeeds restore the previous content, but this is not robust: if the input is valid, a job that it contains could be started if the clock happens to go past a minute before you restore the previous content, and if someone else modifies the crontab at the same time, one or both operations will be disrupted.

So what you can do is call crontab in its own playground. One way to do this is to run it in a chroot — a real one or a fake one. You can call fakechroot to create a fake chroot environment without being root. Here's how to populate it, starting from an empty directory:

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
Run Code Online (Sandbox Code Playgroud)

Tweak the location of the executables as appropriate for your system. /lib/ld-linux.so.2 is the dynamic loader; I gave the location for Linux on x86_32, use /lib64/ld-linux-x86-64.so.2 for Linux on x86_64, etc. You can find the location by running ldd /bin/cat and noting the one for which a single absolute path is given.

The last command returns 0 if the crontab is valid (it also modifies var/spool/cron/crontabs/temp). It returns an error status and prints an error message if the crontab is invalid.

sleep 1 ensures that crontab won't think that the file hasn't changed (some implementations check the modification time, and some filesystems only have 1-second granularity for file timestamps). To avoid the delay, you could copy the touch utility instead of sleep, and arrange to change the timestamp by setting (if you have GNU touch)

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