Якщо вам необхідно запустити завдання в Linux одноразово, використання cron може бути надмірним. Для таких цілей чудово підійде сімейство команд `at` та `batch`. Команда `at` дозволяє запланувати виконання завдання на конкретний час, тоді як `batch` запускає процес, коли система має достатньо вільних ресурсів.
Планування завдань в Linux
Демон cron відповідає за виконання задач у встановлений час. Заплановані програми та команди виконуються у фоновому режимі, що робить cron зручним для регулярних завдань. Він дозволяє гнучко налаштовувати періодичність: щогодини, щодня, щомісяця або щорічно.
Однак, cron не є оптимальним вибором, якщо потрібно виконати завдання лише один раз. Хоча ви можете налаштувати завдання в cron, потрібно буде потім видалити запис з crontab, що може бути незручним.
У світі Linux, якщо ви зіткнулися з проблемою, є велика ймовірність, що хтось інший вже знайшов її рішення. Завдяки довгій історії Unix-подібних систем, існує багато інструментів для вирішення різноманітних задач.
Для одноразового планування завдань, існує спеціальний набір команд.
Інсталяція команди `at`
Для деяких дистрибутивів, наприклад Ubuntu 18.04 та Manjaro 18.1.0, команду `at` необхідно встановити додатково. Fedora 31 зазвичай поставляється з вже встановленим `at`.
Для встановлення в Ubuntu, використовуйте команду:
sudo apt-get install at
Після завершення інсталяції, запустіть демон `at` наступною командою:
sudo systemctl enable --now atd.service
На Manjaro, встановлення `at` виконується командою:
sudo pacman -Sy at
Після інсталяції, запустіть демон `at` за допомогою цієї команди:
sudo systemctl enable --now atd.service
Для перевірки статусу демона `atd` в будь-якому дистрибутиві, виконайте:
ps -e | grep atd
Інтерактивне використання команди `at`
Для використання `at` необхідно задати дату та час запуску. Існує велика гнучкість у форматі часу, що буде розглянуто пізніше.
Незважаючи на те, що ми використовуємо `at` в інтерактивному режимі, час та дату потрібно задати наперед. Якщо не ввести час або ввести щось недійсне, `at` поверне повідомлення “Спотворений час”, як показано нижче:
at
at banana
Дата та час можуть бути задані абсолютно або відносно. Наприклад, для запуску команди через хвилину можна використати “now” та додати “1 minute”, як показано нижче:
at now + 1 minute
Після введення команди, `at` виведе повідомлення і запит, чекаючи введення команд для планування. Зверніть увагу на наступне повідомлення:
Повідомлення вказує, що буде запущено екземпляр оболонки `sh` і команди будуть виконуватися в ній. Ваші команди не будуть виконуватися в Bash, який є більш функціональною оболонкою, але сумісний з sh.
Якщо ваші команди або скрипти використовують функції Bash, яких немає в sh, вони можуть не спрацювати.
Для перевірки роботи команд у sh, запустіть оболонку sh, ввівши `sh`:
sh
Командний рядок зміниться на знак долара ($), тепер можна тестувати команди.
Для повернення до Bash, введіть `exit`:
exit
Ви не отримаєте виводу або повідомлень про помилки від команд, оскільки sh працює як фонове завдання без інтерфейсу.
Будь-який вивід команд – успішний або з помилками – буде надіслано вам електронною поштою. Повідомлення надсилається через внутрішню поштову систему користувачеві, який запустив `at`. Для цього необхідно налаштувати внутрішню систему електронної пошти.
Багато систем Linux не мають внутрішньої поштової системи через її рідку необхідність. Зазвичай використовують sendmail або postfix. Якщо у вас немає поштової системи, ви можете переспрямувати вивід у файли для ведення журналу.
Якщо команда не генерує ніякого виводу або повідомлень про помилки, ви не отримаєте листа. Багато команд Linux вважають мовчання ознакою успіху, тому часто повідомлення не надходять.
Тепер, давайте введемо команду для `at`. Для прикладу використаємо скрипт `sweep.sh`, який видаляє файли з розширеннями *.bak, *.tmp та *.o. Введіть шлях до скрипту та натисніть Enter.
З’явиться новий командний рядок, де можна додати більше команд. Зазвичай, зручніше використовувати скрипт для набору команд.
Натисніть Ctrl+D для завершення введення команд. З’явиться
Після виконання, перевірте внутрішню пошту, ввівши:
Якщо пошти немає, вважайте виконання успішним. Звичайно, можна перевірити наявність файлів *.bak, *.tmp та *.o для підтвердження.
Запустіть все знову за допомогою:
at now + 1 minute
Через хвилину перевірте пошту ще раз:
Ми отримали пошту! Для перегляду повідомлення номер 1, введіть 1 та натисніть Enter.
Лист надійшов від `at`, оскільки скрипт створив повідомлення про помилки. В цьому прикладі не було файлів для видалення, оскільки вони були видалені раніше.
Для видалення листа, натисніть D+Enter, а для виходу з поштової програми, натисніть Q+Enter.
Формати дати та часу
Існує велика гнучкість у форматах часу, які можна використовувати з командою `at`. Ось декілька прикладів:
Запуск о 11:00:
at 11:00 AM
Запуск завтра о 11:00:
at 11:00 AM tomorrow
Запуск о 11:00 цього дня наступного тижня:
at 11:00 AM next week
Виконати в цей час, цього дня наступного тижня:
at next week
Запуск о 11:00 наступної п’ятниці:
at 11:00 AM next fri
Запуск наступної п’ятниці в цей час:
at next fri
Запуск о 11:00 цієї дати наступного місяця:
at 11:00 AM next month
Запуск о 11:00 на певну дату:
at 11:00 AM 3/15/2020
Запуск через 30 хвилин:
at now + 30 minutes
Запуск через дві години:
at now + 2 hours
Запуск завтра в цей час:
at tomorrow
Запуск в цей час у четвер:
at thursday
Запуск о 12:00:
at midnight
Запуск о 12:00:
at noon
Для гурманів чаю, заплануйте завдання на 16:00:
at teatime
Перегляд черги завдань
Для перегляду запланованих завдань, використовуйте команду `atq`:
Команда `atq` відображає наступну інформацію для кожного завдання:
- Ідентифікатор завдання
- Дата виконання
- Час виконання
- Черга завдань (позначаються “a”, “b” і т.д.). Звичайні завдання з `at` потрапляють до черги “a”, а завдання з `batch` – до черги “b”
- Користувач, який запланував завдання
Використання `at` у командному рядку
Ви також можете використовувати `at` у командному рядку, а не інтерактивно, що зручно для скриптів.
Передайте команди в `at` так:
echo "sh ~/sweep.sh" | at 08:45 AM
Завдання прийнято та заплановано, номер завдання та дата відображаються як завжди.
Використання `at` з файлами команд
Збережіть послідовність команд у файлі, а потім передайте його `at`. Це може бути звичайний текстовий файл, а не виконуваний скрипт.
Для передачі файлу, використовуйте параметр `-f`:
at now + 5 minutes -f clean.txt
Також можна досягти цього переспрямуванням файлу:
at now + 5 minutes < clean.txt
Видалення запланованих завдань
Для видалення завдання з черги, використовуйте команду `atrm`. Спочатку, перевірте чергу за допомогою `atq` для отримання номера завдання, а потім використовуйте його з `atrm`:
atq
atrm 11
atq
Перегляд деталей завдань
Ви можете запланувати завдання на майбутнє, і іноді можна забути, що вони роблять. `atq` показує завдання в черзі, але не їхній вміст. Для детального перегляду завдання, використовуйте параметр `-c`:
Спочатку, отримайте номер завдання за допомогою `atq`:
atq
Тепер, використаємо завдання номер 13 з опцією -c:
at -c 13
Інформація про завдання складається з наступних частин:
- Перший рядок: Команди будуть виконані в оболонці `sh`.
- Другий рядок: Команди виконуються з ідентифікатором користувача та групи 1000. Це значення для користувача, який запустив команду `at`.
- Третій рядок: Користувач, який отримує електронну пошту.
- Четвертий рядок: Маска користувача дорівнює 22. Маска використовується для встановлення дозволів за замовчуванням для файлів, створених у цьому сеансі `sh`. Вона віднімається від 666, даючи 644 (rw-r–r–).
- Дані, що залишилися: Більшість з них є змінними середовища.
- Результати тесту. Перевіряється доступ до каталогу виконання. Якщо тест не вдається, виконання завдання припиняється.
- Команди для виконання. Відображається список команд, а також вміст запланованих скриптів. Зверніть увагу, що хоча скрипт в нашому прикладі вище був написаний для Bash, він буде виконаний в оболонці `sh`.
Команда `batch`
Команда `batch` діє подібно до `at`, але має три суттєві відмінності:
- Команда `batch` використовується лише в інтерактивному режимі.
- Завдання додаються до черги, а `batch` виконує їх, коли середнє навантаження системи падає нижче 1.5.
- З `batch` не вказується дата та час виконання.
Виклик `batch` виконується без параметрів командного рядка:
batch
Додайте завдання так само, як і при використанні `at`.
Контроль доступу до `at`
Файли `at.allow` та `at.deny` в каталозі `/etc` визначають, хто може використовувати команду `at`. За замовчуванням, існує тільки `at.deny`, який створюється під час встановлення `at`.
Ось як вони працюють:
- `at.deny`: містить список користувачів, яким заборонено використовувати `at` для планування завдань.
- `at.allow`: містить список користувачів, які можуть використовувати `at`. Якщо `at.allow` не існує, то `at` використовує тільки `at.deny`.
За замовчуванням, використовувати `at` може кожен. Якщо потрібно обмежити доступ, створіть файл `at.allow` та перелічіть тих, хто може використовувати `at`. Це легше, ніж додавати всіх, хто не має використовувати `at`, до файлу `at.deny`.
Файл `at.deny` виглядає наступним чином:
sudo less /etc/at.deny
Файл містить компоненти ОС, які не можуть використовувати `at`. Багатьом з них заборонено це з міркувань безпеки, тому не видаляйте їх з файлу.
Тепер, відредагуємо `at.allow`. Додамо Dave та Mary, нікому іншому не буде дозволено використовувати `at`.
Введіть:
sudo gedit /etc/at.allow
В редакторі додамо імена, як показано нижче, та збережемо файл.
Якщо інший користувач спробує використати `at`, йому буде відмовлено. Наприклад, користувач Eric спробує виконати:
at
Він отримає відмову:
Еріка немає у файлі `at.deny`. Після додавання будь-кого до `at.allow`, всім іншим буде відмовлено у доступі.
Ідеально для одноразових завдань
Як бачите, `at` і `batch` ідеально підходять для одноразових завдань. Отже:
- Для виконання чогось нерегулярного, заплануйте це за допомогою `at`.
- Для запуску завдання тільки тоді, коли навантаження на систему низьке, використовуйте `batch`.