Як виправити всі ваші проблеми / проблеми, пов’язані з Crontab (Linux)
Це вікі спільноти , якщо ви помітили щось неправильне з цією відповіддю або маєте додаткову інформацію, то будь ласка, відредагуйте її.
По-перше, основна термінологія:
- cron (8) - демон, який виконує заплановані команди.
- crontab (1) - програма, яка використовується для зміни файлів користувача crontab (5).
- crontab (5) - це файл на кожного користувача, який містить інструкції для cron (8).
Далі, освіта про cron:
У кожного користувача системи може бути власний файл crontab. Розташування кореневих та користувацьких файлів crontab залежать від системи, але вони, як правило, нижче /var/spool/cron
.
Існує загальносистемний /etc/crontab
файл, /etc/cron.d
каталог може містити фрагменти crontab, які також читаються та діють cron. У деяких дистрибутивах Linux (наприклад, Red Hat) також /etc/cron.{hourly,daily,weekly,monthly}
є каталоги, сценарії всередині яких виконуватимуться щогодини / день / тиждень / місяць, з привілеєм root.
root завжди може використовувати команду crontab; постійні користувачі можуть або не можуть отримати доступ. Коли ви редагуєте файл crontab за допомогою команди crontab -e
та зберігаєте його, crond перевіряє його на основну дійсність, але не гарантує, що ваш файл crontab правильно сформований. Існує файл, cron.deny
який називається, який визначає, які користувачі не можуть використовувати cron. Розташування cron.deny
файлу залежить від системи і його можна видалити, що дозволить усім користувачам використовувати cron.
Якщо комп'ютер не ввімкнено або демон не працює, а дата / час для запуску команди минув, crond не заповнюватиметься та не запускатиме минулі запити.
Деталі crontab, як сформулювати команду:
Команда crontab представлена одним рядком. Ви не можете використовувати \
команду для розширення команди на кілька рядків. Знак хеш ( #
) представляє коментар, який означає, що що-небудь у цій лінії ігнорується cron. Провідні пробіли та порожні рядки ігноруються.
Будьте ДУЖЕ обережними, використовуючи %
знак відсотка ( ) у вашій команді. Якщо вони не врятуються, \%
вони перетворюються в нові рядки, і все після першого не втеченого %
передається вашій команді на stdin.
Для файлів crontab є два формати:
Кронтабелі користувачів
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
Система широка /etc/crontab
та /etc/cron.d
фрагменти
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * user-name command to be executed
Зауважте, що для останнього потрібне ім’я користувача. Команда буде виконуватися як названий користувач.
Перші 5 полів рядка представляють час (и), коли команду слід виконати. Ви можете використовувати номери або, де це можливо, імена днів / місяців у специфікації часу.
- Поля розділені пробілами або вкладками.
- Кома (
,
) використовується для вказівки списку, наприклад, 1,4,6,8, що означає запуск у 1,4,6,8.
- Діапазони задаються тире (
-
) і можуть поєднуватися зі списками, наприклад, 1-3,9-12, що означає від 1 до 3, а потім між 9 і 12.
/
Символ може бути використаний для введення кроку , наприклад , 2/5 , що означає , починаючи з 2 , то кожні 5 (2,7,12,17,22 ...). Вони не загортаються повз кінця.
- Зірочка (
*
) у полі позначає весь діапазон для цього поля (наприклад, 0-59
для хвилинного поля).
- Діапазони та кроки можна комбінувати, наприклад,
*/2
означає, починаючи з мінімального для відповідного поля, а потім кожні 2, наприклад, 0 хвилин (0,2 ... 58), 1 місяця (1,3 ... 11) тощо.
Налагодження команд cron
Перевірте пошту!
За замовчуванням cron надішле будь-який вихід з команди користувачеві, в якому виконується команда. Якщо виходу немає, пошти не буде. Якщо ви хочете, щоб cron надсилав пошту в інший рахунок, тоді ви можете встановити змінну середовища MAILTO у файлі crontab, наприклад
MAILTO=user@somehost.tld
1 2 * * * /path/to/your/command
Зробіть висновок самостійно
Ви можете перенаправити stdout та stderr у файл. Точний синтаксис для отримання виходу може відрізнятися залежно від того, який оболонку використовується cron. Ось два приклади, які зберігають весь вихід у файл за адресою /tmp/mycommand.log
:
1 2 * * * /path/to/your/command &>/tmp/mycommand.log
1 2 * * * /path/to/your/command >/tmp/mycommand.log 2>&1
Подивіться на колоди
Cron реєструє свої дії через syslog, який (залежно від налаштувань) часто переходить на /var/log/cron
або /var/log/syslog
.
Якщо потрібно, ви можете відфільтрувати заяви cron за допомогою напр
grep CRON /var/log/syslog
Тепер, коли ми переглянули основи cron, де знаходяться файли та як їх використовувати, розглянемо деякі поширені проблеми.
Перевірте, чи працює cron
Якщо cron не працює, то ваші команди не будуть заплановані ...
ps -ef | grep cron | grep -v grep
повинен отримати вам щось подібне
root 1224 1 0 Nov16 ? 00:00:03 cron
або
root 2018 1 0 Nov14 ? 00:00:06 crond
Якщо не перезавантажте його
/sbin/service cron start
або
/sbin/service crond start
Можуть бути й інші методи; використовувати те, що надає ваш дистрибутив.
cron виконує вашу команду в обмеженому середовищі.
Те, що змінні середовища доступні, ймовірно, буде дуже обмеженим. Як правило, ви отримаєте тільки кілька змінних , визначених, наприклад $LOGNAME
, $HOME
і $PATH
.
Особливо слід зазначити, що PATH
це обмежено /bin:/usr/bin
. Переважна більшість проблем "мій сценарій не працює" викликані цим обмежувальним шляхом . Якщо ваша команда знаходиться в іншому місці, ви можете вирішити це двома способами:
Надайте повний шлях до вашої команди.
1 2 * * * /path/to/your/command
Укажіть відповідний PATH у файлі crontab
PATH=/usr:/usr/bin:/path/to/something/else
1 2 * * * command
Якщо вашій команді потрібні інші змінні середовища, їх можна визначити і у файлі crontab.
cron запускає вашу команду cwd == $ HOME
Незалежно від того, де програма, яку ви виконуєте, знаходиться у файловій системі, поточний робочий каталог програми, коли запускається cron, буде домашнім каталогом користувача . Якщо ви отримуєте доступ до файлів у вашій програмі, вам потрібно буде це врахувати, якщо ви використовуєте відносні шляхи або (бажано) просто використовувати повнокваліфіковані контури скрізь, і врятуйте всіх безліч плутанини.
Остання команда в моєму Crontab не працює
Cron, як правило, вимагає, щоб команди закінчувались новим рядком. Відредагуйте свій crontab; перейдіть до кінця рядка, який містить останню команду, і вставте новий рядок (натисніть Enter).
Перевірте формат crontab
Ви не можете використовувати користувацький crontab, відформатований crontab для / etc / crontab або фрагменти в /etc/cron.d і навпаки. Crontab, відформатований користувачем, не включає ім'я користувача у 6-му положенні рядка, тоді як системний формат crontab включає ім'я користувача та виконує команду як цей користувач.
Я поміщаю файл у /etc/cron.{hourly,daily,weekly,monthly}, і він не працює
- Перевірте, чи немає у файлі розширення, див. Прогони
- Переконайтеся, що файл має дозволи на виконання.
- Скажіть системі, що використовувати під час виконання сценарію (наприклад, поставити
#!/bin/sh
вгорі)
Помилки, пов’язані з датою Cron
Якщо ваша дата нещодавно змінилася користувачем або системою, оновленням часу, часовим поясом чи іншим, то crontab почне поводитися нестабільно і виявлятиме химерні помилки, іноді працює, іноді ні. Це спроба crontab спробувати "робити те, що ти хочеш", коли час змінюється з-під нього. Поле "хвилини" стане неефективним після зміни години. У цьому сценарії приймаються лише зірочки. Перезапустіть cron і повторіть спробу, не підключаючись до Інтернету (тому дата не має шансу повернутися на один із серверів часу).
Знову знаки відсотків
Щоб підкреслити поради щодо знаків відсотків, ось приклад того, що cron робить з ними:
# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz
створить файл ~ / cron.out, що містить 3 рядки
foo
bar
baz
Це особливо нав'язливо при використанні date
команди. Обов’язково уникайте знаків відсотків
* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"