我试图了解为什么 cron 拒绝使用某个 crontab 文件。crontab 的手册页显示:
cron 要求 crontab 中的每个条目都以换行符结尾。如果 crontab 中的最后一项缺少换行符,cron 将认为该 crontab(至少是部分)已损坏并拒绝安装它。
给定以下 cron 文件:
# 由 Fabric$ 管理 $ SHELL=/bin/sh$ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin$ $ # mh dom mon dow 用户命令$ 17 * * * * root cd / && run-parts --report /etc/cron.hourly$ 25 6 * * * root 测试 -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )$ 47 6 * * 7 root 测试 -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )$ 52 6 1 * * root 测试 -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )$ $ # Postgres 监控$ * * * * * postgres cd / && /etc/cron.d/pgup.sh$ */5 * * * * postgres cd / && /etc/cron.d/aws-scripts-mon/mon-put-instance-data.pl --mem-avail --disk-space-util --disk-path=/mnt$ $ # Postgres 备份$ 00 00 * * * postgres /etc/cron.d/pgbackup.sh$
注意“$”字符表示 LF(vim unix 格式)字符。
当我重新启动 cron 时,我在 syslog 中收到以下错误:
3 月 31 日 17:34:02 postgres-primary0 cron[30852]: (系统) 错误(EOF 前缺少换行符,此 crontab 文件将被忽略)
并且在cron文件末尾添加一个空行,导致重新启动cron时不会出现错误。
结论:
据我所知,最后一条确实以换行符结尾。因此,crontab 似乎无法识别它。
这是错误吗?也许本来的意图是文件末尾有一行换行符,但文档中的说法却有误导性。或者我可能没有正确理解“换行符”的含义……如果能就此问题做出澄清,我将不胜感激。
答案1
这是一个错误吗?
不。我创建了一个文件,文件末尾没有换行符。然而 Vim(之后:set list
)显示$
在末尾。看来你的前提是错误的,你的文件缺少最后一个换行符,cron 工作正常。
笔记:
POSIX需要尾随换行符才能将任何行视为完整。
3.195 不完整行
文件末尾的一个或多个非 <换行符> 字符序列。[…]
3.206 行
零个或多个非 <newline> 字符加上终止 <newline> 字符的序列。因此,cron 的行为并非随意的怪癖(尽管该工具可能没有那么严格)。有关更多信息,请参阅为什么文本文件要以换行符结尾?
使用默认设置的 Vim 将在保存时修复丢失的换行符,除非你告诉它不要。
要判断末尾是否有换行符,请对文件进行十六进制转储,例如
hexdump the_file
或xxd the_file
。对于您的 crontab 来说,这可能很难。在我的 Debian 中,crontab 是,但由于我作为普通用户/var/spool/cron/crontabs/kamil
无法访问,因此我无法只访问文件。为了克服这个问题,我可以使用以下技巧:/var/spool/cron/crontabs/
xxd
EDITOR=xxd crontab -e
当且仅当最后一个字节报告为 ,末尾才会有一个换行符
0a
。