8

I'm trying to understand why cron is refusing to work with a certain crontab file. The manpage for crontab says:

cron requires that each entry in a crontab end in a newline character. If the last entry in a crontab is missing the newline, cron will consider the crontab (at least partially) broken and refuse to install it.

Given the following cron file:

# managed by Fabric$
$
SHELL=/bin/sh$
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin$
$
# m h dom mon dow user  command$
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly$
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )$
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )$
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )$
$
# Postgres monitoring$
*  *    * * *   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 Backup$
00 00   * * *   postgres /etc/cron.d/pgbackup.sh$

Noting that the "$"character indicates a LF (vim unix format) character.

And I receive the following error in syslog when I restart cron:

Mar 31 17:34:02 postgres-primary0 cron[30852]: (system) ERROR (Missing newline before EOF, this crontab file will be ignored)

And adding a blank line at the end of the cron file results in no error when restarting cron.

Conclusion:

As far as I can tell the last entry does end in a newline character. So it seems like crontab is not recognizing it.

Is this a bug? Maybe what was intended was that there be a newline on its own line at the end of the file, in which case the documentation is misleading. Or possibly I'm not understanding "newline" correctly in this context...Some clarification on this matter will be appreciated.

3
  • 2
    I'm afraid you misinterpret the $ sign here. It just shows you the end of the line (an imaginary place after the last character of that line) and not a linebreak.
    – user556625
    Commented Mar 31, 2016 at 19:27
  • @GombaiSándor the $ thanks for the comment. as I understand it the $ is an eol character, and since it is unix format in vim the eol character should be \n. If I search for \n I also get a match at the end of the last line.
    – lps
    Commented Mar 31, 2016 at 20:40
  • 1
    You are right, using vim which puts the \n there I have never met this but now I set EDITOR=mcedit for a try and dropped out the last \n causing: "crontab: installing new crontab new crontab file is missing newline before EOF, can't install. Do you want to retry the same edit? (y/n)" So it looks really vital. I can't argue for it... probably just history.
    – user556625
    Commented Mar 31, 2016 at 21:05

1 Answer 1

5

Is this a bug?

No. I created a file with no newline character at the end. Nevertheless Vim (after :set list) shows $ at the end. It looks like your premise is false, your file is missing a final newline, cron works as intended.


Notes:

  • POSIX requires a trailing newline character to consider any line to be complete.

    3.195 Incomplete Line
    A sequence of one or more non-<newline> characters at the end of the file.

    […]

    3.206 Line
    A sequence of zero or more non-<newline> characters plus a terminating <newline> character.

    So the behavior of cron is not just an arbitrary quirk (although the tool might not be that restrictive). For more insight see Why should text files end with a newline?

  • Vim with default settings will fix the missing newline while saving, unless you tell it not to.

  • To tell whether there is a newline character at the end or not, make a hexdump of the file, e.g. hexdump the_file or xxd the_file. In case of your crontab this may be hard. In my Debian the crontab is /var/spool/cron/crontabs/kamil, but since I have no access to /var/spool/cron/crontabs/ as a normal user, I cannot just xxd the file. To overcome this I can use the following trick:

    EDITOR=xxd crontab -e
    

    There is a newline at the end iff the last byte reports as 0a.

1
  • This is interesting. macOS will happily work with crontab files without a trailing newline.
    – slhck
    Commented Oct 5, 2022 at 15:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .