ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

cron и crontab: расписания, окружение и пропущенные запуски

Автор: · Обновлено

cron запускает команды по календарному расписанию. Он удобен для периодического отчёта или очистки учебных данных, но команда должна работать без интерактивного терминала. Успешный ручной запуск ещё не доказывает работоспособность задания: отличаются рабочий каталог, PATH, пользователь и доступные переменные.

Где хранится расписание

crontab -l показывает таблицу текущего пользователя, crontab -e открывает редактор. Перед правкой сохраните вывод в отдельный файл; сообщение об отсутствии таблицы у нового пользователя нормально. sudo crontab -l читает таблицу root, а не вашу. В пользовательской записи после пяти временных полей сразу идёт команда; в /etc/crontab и файлах /etc/cron.d/ между расписанием и командой указан пользователь.

Не выполняйте crontab файл для установки одного нового задания поверх существующей таблицы: эта команда заменяет её целиком. Для первой практики достаточно подготовить текст расписания и проверить сам скрипт; устанавливать задания на рабочей машине не требуется.

Пять полей и примеры

# минута час день-месяца месяц день-недели команда
*/5 * * * * /home/student/bin/report.sh
30 2 * * * /home/student/bin/report.sh
0 9 * * 1-5 /home/student/bin/report.sh
@reboot /home/student/bin/start-demo.sh

Первая строка означает минуты 0, 5, 10 и далее внутри каждого часа, вторая — ежедневно в 02:30, третья — в 09:00 по будням. @reboot выполняется при запуске cron, поэтому не гарантирует готовность сети и удалённого диска. Шаг */5 отсчитывается внутри поля, а не через пять минут после конца предыдущей работы.

Если одновременно ограничить день месяца и день недели, классический cron обычно запускает при совпадении любого из этих условий. Поэтому «первый понедельник месяца» не задают простым 0 9 1-7 * 1: понадобится проверка внутри скрипта или календарное выражение systemd. Поведение специальных расширений сверяйте с установленной реализацией.

Воспроизвести бедное окружение

cron_lab=$(mktemp -d)
cat >"$cron_lab/report.sh" <<'SH'
#!/bin/sh
set -eu
printf 'report started\n'
printf 'working_directory=%s\n' "$PWD"
/usr/bin/date -u '+%Y-%m-%dT%H:%M:%SZ'
SH
chmod 700 "$cron_lab/report.sh"
env -i HOME="$cron_lab" PATH=/usr/bin:/bin /bin/sh "$cron_lab/report.sh" >"$cron_lab/report.log" 2>&1
cat "$cron_lab/report.log"

В журнале ожидаются маркер начала, текущий каталог и время UTC. Этот запуск проверяет зависимость от окружения, но не работу демона cron. В реальном задании используйте абсолютный путь, явный cd при необходимости и установленные зависимости. .bashrc автоматически не читается; shell по умолчанию часто /bin/sh. Для Bash-синтаксиса задайте shebang и запускайте исполняемый файл либо явно /bin/bash.

Логи и пересечение запусков

Пример пользовательской записи для заранее подготовленных каталогов:

SHELL=/bin/sh
PATH=/usr/bin:/bin
*/5 * * * * /usr/bin/flock -n /home/student/.cache/report.lock /home/student/bin/report.sh >>/home/student/log/report.log 2>&1

>> дописывает stdout, 2>&1 туда же направляет ошибки. Каталоги должны существовать и принадлежать нужному пользователю. flock держит блокировку до завершения команды; при занятом lock и -n новый запуск пропускается, а не встаёт в очередь. Если ни один запуск терять нельзя, нужны очередь и учёт результата. Учтите ротацию журнала: без неё успешное расписание само способно заполнить диск.

Символ % в командной части crontab имеет особое значение, даже внутри shell-кавычек: неэкранированный остаток передаётся в stdin после преобразования. Вынесите date +%F в скрипт или экранируйте процент именно для crontab. В скрипте дополнительное cron-экранирование уже не требуется.

Часовой пояс и пропущенное время

Проверьте часовой пояс через timedatectl, а реализацию — по пакету cron/cronie. Cronie поддерживает CRON_TZ=Europe/Moscow, но это расширение не универсально; обычный TZ может менять только окружение команды. Переход на летнее время способен пропустить или повторить час, правила зависят от реализации. Для бизнес-операции храните обработанный период и избегайте повторных эффектов.

Обычный cron не компенсирует задания, пропущенные во время выключения. Для такой потребности подходят anacron с его ограничениями либо systemd timer с OnCalendar и Persistent=true. Последний инициирует один пропущенный запуск, а не воспроизводит все отсутствующие минуты. Длительность самой команды и готовность её ресурсов остаются отдельными условиями.

Ошибка и диагностика

При «cron не запускает скрипт» сначала проверьте crontab -l, пользователя, путь и права. Затем статус службы: на Debian/Ubuntu это обычно systemctl status cron, на системах с Cronie — systemctl status crond. Журнал ищут через соответствующий journalctl -u. Отличайте отсутствие запуска от запуска с ошибкой: маркер в начале скрипта помогает увидеть границу. Перезапускать службу после каждого crontab -e обычно не требуется.

Практика

Подготовьте расписание ежедневного отчёта и отдельно объясните все пять полей. Выполните скрипт с очищенным окружением, затем дважды запустите длинную учебную команду под одним flock: вторая должна отказаться от параллельной работы. Добавьте журнал и проверьте оба кода выхода. Зафиксируйте, что произойдёт при выключенном компьютере в назначенное время, и выберите механизм, если пропуск недопустим.

Что важно запомнить

Расписание, окружение и повторяемость результата проверяются отдельно. У задания должны быть владелец, наблюдаемый исход и понятное поведение при долгом исполнении, смене времени и недоступных зависимостях.

Частые вопросы

Почему каждые пять минут появились параллельные процессы?

cron не ждёт завершения прошлой команды. Если она занимает дольше интервала, экземпляры пересекаются; добавьте блокировку или используйте сервис с контролируемым состоянием.

Можно ли записать пароль в crontab?

Такая запись осложняет контроль доступа и обслуживание. Передавайте секрет способом приложения через защищённый файл или менеджер секретов, не через аргументы, видимые в списке процессов.

Почему вручную работает, а по расписанию нет?

Сравните пользователя, каталог, PATH и переменные. Повторение через env -i часто обнаруживает скрытую зависимость от интерактивной настройки быстрее, чем случайное добавление sudo.

Источники