cron najwyraźniej wymaga znaku nowej linii we własnej linii na końcu pliku

5

Próbuję zrozumieć, dlaczego cron odmawia pracy z pewnym plikiem crontab. Strona podręcznika crontab mówi:

cron wymaga, aby każdy wpis w crontab kończył się znakiem nowej linii. Jeśli brakuje ostatniego wpisu w crontabie nowej linii, cron uzna crontab (przynajmniej częściowo) za uszkodzony i odmówi jego zainstalowania.

Biorąc pod uwagę następujący plik cron:

# zarządzany przez Fabric $
$
SHELL = / bin / sh $
ŚCIEŻKA = / usr / local / sbin: / usr / local / bin: / sbin: / bin: / usr / sbin: / usr / bin $
$
# mh dom mon dow polecenie użytkownika $
17 * * * * root cd / && run-parts - raport /etc/cron.hourly$
25 6 * * * test root -x / usr / sbin / anacron || (cd / && run-parts --report /etc/cron.daily) $
47 6 * * 7 test root -x / usr / sbin / anacron || (cd / && run-parts --report /etc/cron.weekly) $
52 6 1 * * test root -x / usr / sbin / anacron || (cd / && run-parts --report /etc/cron.monthly) $
$
# Monitorowanie 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 $
$
# Kopia zapasowa Postgres $
00 00 * * * postgres /etc/cron.d/pgbackup.sh$

Zauważ, że znak „$” oznacza znak LF (format uniksowy vim).

Po ponownym uruchomieniu crona pojawia się następujący błąd w syslog:

31 marca 17:34:02 postgres-primary0 cron [30852]: ( system ) ERROR (Brak nowego wiersza przed EOF, ten plik crontab zostanie zignorowany)

Dodanie pustej linii na końcu pliku cron nie powoduje błędu przy ponownym uruchomieniu crona.

Wniosek:

O ile wiem, ostatni wpis kończy się znakiem nowej linii. Wygląda więc na to, że crontab go nie rozpoznaje.

Czy to błąd? Być może zamierzano, aby na końcu pliku znajdował się nowy wiersz we własnej linii, w którym to przypadku dokumentacja wprowadza w błąd. A może nie rozumiem poprawnie „nowego wiersza” w tym kontekście ... Pewne wyjaśnienie tej kwestii zostanie docenione.

lps
źródło
2
Obawiam się, że źle zinterpretowałeś tutaj znak $. Pokazuje tylko koniec linii (wyimaginowane miejsce po ostatnim znaku tej linii), a nie podział linii.
Gombai Sándor
@ GombaiSándor $ dzięki za komentarz. jak rozumiem, $ jest znakiem eol, a ponieważ jest to format uniksowy w vimie, znak eol powinien być \ n. Jeśli szukam \ n, dostaję dopasowanie również na końcu ostatniej linii.
lps
Masz rację, używając vima, który umieszcza \ n tam nigdy tego nie spotkałem, ale teraz ustawiam EDITOR = mcedit na próbę i porzuciłem ostatnią \ n powodując: "crontab: instalowanie nowego pliku crontab nowego pliku crontab brakuje nowej linii przed EOF , nie można zainstalować. Czy chcesz ponowić tę samą edycję? (t / n) „Więc wygląda to naprawdę niezbędne. Nie mogę się o to kłócić ... prawdopodobnie tylko historia.
Gombai Sándor

Odpowiedzi:

1

Czy to błąd?

Nie. Utworzyłem plik bez znaku nowej linii na końcu. Niemniej Vim (po :set list) pokazuje $na końcu. Wygląda na to, że twoja przesłanka jest fałszywa, w pliku brakuje ostatniej nowej linii, cron działa zgodnie z przeznaczeniem.


Uwagi:

  • POSIX wymaga znaku końca nowej linii, aby uznać dowolny wiersz za kompletny.

    3.195 Niekompletna linia
    Sekwencja jednego lub więcej znaków innych niż <wolny> na końcu pliku.

    […]

    3.206 Wiersz
    Sekwencja zerowa lub więcej znaków innych niż <lineline> oraz kończący znak <lineline>.

    Zachowanie crona nie jest więc zwykłym dziwactwem (chociaż narzędzie może nie być tak restrykcyjne). Aby uzyskać więcej informacji, zobacz Dlaczego pliki tekstowe powinny kończyć się nową linią?

  • Vim z ustawieniami domyślnymi naprawi brakującą nową linię podczas zapisywania, chyba że powiesz, żeby tego nie robić .

  • Aby stwierdzić, czy na końcu jest znak nowej linii, wykonaj zrzut heksowy pliku, np . hexdump the_fileLub xxd the_file. W przypadku twojego crontaba może to być trudne. W moim Debianie jest to crontab /var/spool/cron/crontabs/kamil, ale ponieważ nie mam dostępu /var/spool/cron/crontabs/jako zwykły użytkownik, nie mogę tylko xxdpliku. Aby temu zaradzić, mogę zastosować następującą sztuczkę:

    EDITOR=xxd crontab -e
    

    Na końcu znajduje się nowa linia w ostatnim bajcie raportów jako 0a.

Kamil Maciorowski
źródło