Автоматизация задач с помощью cron в Ubuntu 18.04
Cron – это хронологический демон, планировщик задач Unix-подобных операционных систем. Cron работает в фоновом режиме. Задачи, запланированные в cron, называются «cron jobs» и запускаются автоматически. Благодаря этому cron очень удобно использовать для поддержки сервера без вмешательства администратора.
Данный мануал научит вас планировать задачи в cron с помощью специального синтаксиса. Также мы познакомим вас с горячими клавишами и сокращениями, которые помогут вам быстрее писать и читать задачи cron.
Требования
Для работы вам понадобится машина Ubuntu 18.04. Это может быть ваш локальный компьютер, виртуальная машина или виртуальный выделенный сервер.
Вне зависимости от того, какую машину вы используете, вы должны настроить ее по этому мануалу.
1: Установка cron
Почти в каждом дистрибутиве Linux cron в каком-то виде установлен по умолчанию. Но если на вашей машине демона cron нет, вы можете установить его с помощью менеджера пакетов.
Для начала обновите индекс локальных пакетов.
Затем установите cron с помощью этой команды:
Также нужно запустить программу в фоновом режиме:
sudo systemctl enable cron
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable cron
Теперь в вашей системе установлен демон cron, и вы можете приступать к планированию заданий.
2: Как работает cron
Задачи cron записываются в специальный файл crontab, с помощью которого можно ими управлять. Каждый профиль пользователя в системе может иметь свой собственный файл crontab в каталоге /var/spool/cron/crontabs/.
Чтобы запланировать задачу, нужно просто открыть crontab в редакторе и добавить в файл выражение cron. Синтаксис выражений cron содержит два элемента: время и команду, которую нужно запустить.
Через cron запускается практически любая команда, которую можно использовать в командной строке. Время содержит 5 полей, которые записываются в следующем порядке:
Поле | Допустимые значения |
минуты | 0-59 |
часы | 0-23 |
день месяца | 1-31 |
месяц | 1-12 или JAN-DEC |
День недели | 0-6 или SUN-SAT |
В целом записи в crontab структурированы следующим образом:
minute hour day_of_month month day_of_week command_to_run
Вот рабочий пример выражения cron. Оно запускает команду curl http://www.google.com каждый вторник в 17:30.
30 17 * * 2 curl http://www.google.com
Также cron предоставляет несколько специальных символов, которые можно включить в ту часть выражения cron, которая определяет время, чтобы упростить планирование:
- *: это подстановочная переменная, которая значит «все». Следовательно, задача, запланированная с помощью * * * * * …, будет запускаться каждую минуту каждого часа каждого дня каждого месяца.
- ,: символы запятой разделяют значения календаря и формируют список. Если вы хотите, чтобы задача выполнялась в начале и середине каждого часа, вы можете настроить такое поведение в рамках одного выражения с помощью следующего синтаксиса: например, 0 * * * * … и 30 * * * * … можно объединить в выражение 0,30 * * * * ….
- -: дефис задает диапазон значений в поле времени. С его помощью вместо 30 отдельных выражений для одной команды, которую вы хотите запускать в течение первых 30 минут каждого часа (0 * * * * …, 1 * * * * …, 2 * * * * .. и т. д.), вы можете просто использовать одно выражение 0-29 * * * * ….
- /: слеш вместе со звездочкой определяет шаг. Например, чтобы не команда запускалась каждые три часа, вы можете запланировать ее следующим образом: 0 * / 3 * * * …. При этом не придется создавать восемь отдельных задач cron (, 0 0 * * * …, 0 3 * * * …, 0 6 * * * … и так далее).
Примечание: Нельзя выражать значения шага произвольно. Вы можете использовать только целые числа, на которые заданный диапазон можно разделить без остатка. Например, в поле «часы» вы можете использовать слеш только с цифрами 1, 2, 3, 4, 6, 8 или 12 (на них можно разделить 24 часа без остатка).
Вот еще немного примеров планирования времени в cron:
- * * * * * – команда будет запускаться каждую минуту.
- 12 * * * * – команда запускается на 12 минуте каждого часа.
- 0,15,30,45 * * * * – команда запускается каждые 15 минут.
- */15 * * * * – Run the command every 15 minutes.
- 0 4 * * * – команда запускается каждый день в 4:00 утра.
- 0 4 * * 2-4 – команда будет запускаться каждый вторник, среду и четверг в 4:00 утра.
- 20,40 */8 * 7-12 * – команда запускается на 20-й и 40-й минуте каждого 8-го часа каждый день последних 6 месяцев года.
Если вам сложно разобраться с этим вопросом или вам нужна помощь в планировании времени для ваших задач cron, обратитесь к Cronitor. Он предоставляет удобный редактор выражений времени cron по имени Crontab Guru, который вы можете использовать для проверки.
3: Управление файлами crontab
Как только вы определились с расписанием задач и знаете, какую задачу хотите запланировать, вам нужно поместить ее в файл, чтобы демон смог ее прочитать.
Ранее мы говорили, что crontab – это специальный файл, который содержит расписание задач для cron. Однако файл crontab не предназначен для непосредственного редактирования. Вместо этого рекомендуется использовать команду crontab. Она будет редактировать crontab вашего пользователя, не меняя ваших привилегий с помощью sudo. Команда crontab также выявляет синтаксические ошибки в файле crontab (а редактируя файл вручную, вы можете их не заметить).
Чтобы отредактировать crontab, введите:
Если вы впервые запускаете команду crontab в этом профиле пользователя, вам будет предложено выбрать текстовый редактор по умолчанию, который будет использоваться при редактировании вашего файла crontab в дальнейшем:
no crontab for 8host — using an empty one
Select an editor. To change later, run ‘select-editor’.
1. /bin/nano 2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]:
Введите номер, соответствующий редактору, который вы хотите выбрать. Чтобы принять вариант по умолчанию, nano, просто нажмите ENTER.
После этого вы попадете в новый файл crontab, содержащий некоторые закомментированные инструкции о том, как его использовать:
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use ‘*’ in these fields (for ‘any’).#
# Notice that tasks will be started based on the cron’s system
# daemon’s notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
Когда вы в будущем запустите команду crontab -e, она автоматически вызовет ваш crontab в этом текстовом редакторе. Здесь вы можете ввести расписание своих задач (каждая запись должна находиться в отдельной строке). Чтобы сохранить и закрыть crontab, нажмите CTRL + X, Y, затем ENTER, если вы выбрали nano.
Примечание: В системах Linux в каталоге /etc/ хранится еще один файл crontab. Это общесистемный crontab, в котором есть дополнительное поле, оно определяет пользователя, который должен выполнять задачу cron. В этом мануале рассматриваются только пользовательские файлы crontab. Если вы хотите отредактировать общесистемный crontab, вы можете сделать это с помощью следующей команды:
Если вы хотите просмотреть содержимое вашего crontab, но не редактировать его, вы можете использовать следующую команду:
Важно! Следующая команда не не требует подтверждения, а сразу удаляет все команды из crontab. Запускайте ее, только если вы уверены, что хотите очистить файл.
Вы можете очистить свой crontab с помощью следующей команды:
Эта команда немедленно очистит пользовательский crontab. Чтобы команда все же запросила подтверждения на очистку crontab, вы можете включить флаг –i:
crontab -r -i
crontab: really delete 8host’s crontab? (y/n)
При появлении запроса вы должны ввести y, чтобы удалить crontab, или n, чтобы отменить действие.
4: Управление выводом cron
Поскольку задачи cron выполняются в фоновом режиме, их результат не всегда очевиден. Теперь, когда вы знаете, как использовать команду crontab и как планировать задачи в cron, вы можете познакомиться с несколькими способами перенаправления вывода cron, что поможет вам отслеживать их выполнение.
Если на вашем сервере установлен и настроен агент пересылки почты, например Sendmail, вы можете отправить выходные данные задач cron на адрес электронной почты, связанный с вашим профилем пользователя Linux. Вы также можете вручную указать адрес электронной почты, добавив параметр MAILTO в верхней части crontab.
Например, попробуйте добавить следующие строки в crontab. Среди них есть оператор MAILTO, за которым следует условный электронный адрес, директива SHELL, которая задает оболочку (в этом примере bash), директива HOME, указывающая путь, по которому следует искать двоичный файл cron, и одна задача cron:
. . .
MAILTO=»example@my-email.com»
SHELL=/bin/bash
HOME=/
* * * * * echo ‘Run this command every minute’
Эта конкретная задача будет возвращать строку «Run this command every minute», и этот вывод будет каждую минуту отправляться на адрес электронной почты, указанный в директиве MAILTO.
Вы также можете перенаправить вывод задачи cron в лог или в пустое место, чтобы не получать его на почту.
Чтобы направить вывод запланированной команды в лог, добавьте >> в конец команды, а затем укажите имя и расположение лога:
* * * * * echo ‘Run this command every minute’ >> /directory/path/file.log
Допустим, вы хотите использовать cron для запуска скрипта, но оставить его в фоновом режиме. Для этого вы можете перенаправить вывод скрипта в пустое место, например /dev/null, которое немедленно удаляет все записанные в него данные. Следующее выражение cron запускает скрипт PHP в фоновом режиме:
* * * * * /usr/bin/php /var/www/domain.com/backup.php > /dev/null 2>&1
Это задание cron также перенаправляет стандартную ошибку (представленную 2) на стандартный вывод (>&1). Поскольку стандартный вывод уже перенаправляется в /dev/null, скрипт будет работать без вывода сообщений. Даже если crontab содержит директиву MAILTO, выходные данные не будут отправляться на указанный адрес электронной почты.
5: Ограничение доступа
Вы можете указать, каким пользователям разрешено использовать команду crontab, с помощью файлов cron.allow и cron.deny, которые хранятся в каталоге /etc/. Если файл cron.deny существует, любому из перечисленных в нем пользователей будет запрещено редактировать свой crontab. Если файл cron.allow существует, только пользователи, перечисленные в нем, смогут редактировать свои файлы crontab. Если оба файла существуют и в каждом из них указан один и тот же пользователь, файл cron.allow переопределит cron.deny, и в результате пользователь сможет редактировать свой crontab.
Чтобы запретить всем пользователям доступ к своим файлам, а затем предоставить доступ пользователю ishmael, вы можете использовать следующую последовательность команд:
sudo echo ALL >>/etc/cron.deny
sudo echo ishmael >>/etc/cron.allow
Сначала команда блокирует всех пользователей, добавляя ALL в файл cron.deny. Затем мы вносим имя пользователя ishmael в файл cron.allow, что открывает ему доступ к выполнению cron.
Если у пользователя есть права sudo, он может редактировать crontab другого пользователя с помощью следующей команды:
Но если cron.deny существует, пользователь user-2 указан в нем и не указан в cron.allow, после выполнения предыдущей команды вы получите следующую ошибку:
The user user-2 cannot use this program (crontab)
6: Специальный синтаксис
cron предлагает несколько сокращений для команд, которые вы можете использовать в файле crontab, чтобы упростить планирование. По сути они являются ярлыками для определенных значений.
Сокращение | Стандартная запись |
@hourly | 0 * * * * |
@daily | 0 0 * * * |
@weekly | 0 0 * * 0 |
@monthly | 0 0 1 * * |
@yearly | 0 0 1 1 * |
Примечание: Не все демоны cron поддерживают этот синтаксис (особенно это касается устаревших версий), потому обязательно проверьте, работает ли ваше выражение.
Также есть сокращение @reboot, оно запустит любую указанную после него команду при запуске сервера:
@reboot echo «System start up»
Эти сокращения помогут вам упростить запись и чтение задач в вашем crontab.
Заключение
Cron – это гибкая и мощная утилита, которая упрощает задачи, связанные с системным администрированием. В сочетании со скриптами оболочки cron может автоматизировать часто повторяющиеся сложные задачи.