Что было. Резервное копирование через rsnapshot перенесли с cron на anacron. Из anacron задание падает: ERROR: Interval "daily" unknown, check /etc/rsnapshot.conf. Та же команда rsnapshot daily из терминала работает.
Причина. Файл anacrontab редактировали через веб-панель администрирования, и она сохранила его с переводами строк в стиле DOS (\r\n). anacron прочитал аргумент как daily\r, и rsnapshot честно не нашёл интервал с таким именем: в ошибке невидимый символ возврата каретки не виден. Автор преобразовал файл в формат Unix; подтверждено.
Как обнаружить.
file /etc/anacrontab # "with CRLF line terminators"
cat -A /etc/anacrontab | head # ^M в конце строк
grep -c $'\r' /etc/anacrontab
Исправление: sed -i 's/\r$//' файл или dos2unix файл (пакет dos2unix).
Где ещё CRLF ломает серверы тихо.
- Скрипты:
#!/bin/bash\rдаётbad interpreter: No such file or directory, хотя/bin/bashесть; в cron это выглядит как «задание не выполняется». crontab: строки с\rмогут не распознаться или передать\rв команду.- Конфиги nginx/Apache/sshd: значения с
\rприводят к «unknown directive» или неверным путям к сертификатам. authorized_keys: ключ с\rв конце не совпадает, вход по ключу отвергается без объяснений.- Переменные окружения в
.envдля Docker Compose и systemdEnvironmentFile: значения получают хвост\r, пароли «не подходят».
Общий признак: ошибка ссылается на строку, которая выглядит правильно.
Откуда берётся. Редакторы на Windows (Блокнот в старых версиях), копирование через веб-формы панелей, вставка из документов, передача файлов в текстовом режиме FTP. В Git полезен .gitattributes с * text=auto eol=lf для серверных репозиториев.
Профилактика. Редактировать конфиги на сервере (nano, vim) или в редакторах с явным выбором LF; после любого «внешнего» редактирования запускать file на файл; в скриптах развёртывания проверка grep -l $'\r' по каталогу конфигов.
Формат описан в документации Ubuntu.