понедельник, 12 марта 2018 г.

Пользовательское задание cron в Linux Mint и Ubuntu


По мере ознакомления с содержанием найденных по поиску публикаций о cron у меня крепло ощущение, что являюсь ярким представителем "тупых" пользователей подкласса "всё равно не въезжаю". Поэтому предлагаю к ознакомлению свою версию подачи материала или, другими словами, личный опыт создания пользовательских заданий cron, которые работали бы по принципу "Настроил и забыл".

Примечание. Так как создание пользовательского задания cron осуществлялось для Linux Mint и Runtu (Runtu является адаптированной к русскоязычному пользователю Ubuntu с графическим окружением xfce), то далее в тексте будут даваться пояснения для обоих дистрибутивов.


1. Где посмотреть расписание заданий cron?

Так как рассматривается задача запуска именно пользовательских заданий cron, то статьи с упоминаниями о cron.hourly, cron.daily, cron.weelky, cron.mounthly в каталоге etc можете даже не читать. По умолчанию, эти задания являются системными и определены для запуска от суперпользователя root. Если интересно, то можете открыть эти каталоги (только для просмотра не потребуется команда sudo) и ознакомиться с содержанием расположенных там файлов. Расписанием этих заданий является файл /etc/crontab

Ваши пользовательские задания будут расположены в каталоге
 /var/spool/cron/crontabs, но под своим именем просмотреть их будет невозможно:


Чтобы удовлетворить своё любопытство, запустите файловый менеджер с правами суперпользователя, например,

  sudo mc, sudo thunar (sudo nemo или sudo caja).

Так как раньше Вы не создавали заданий, то этот каталог будет пуст.


2. Инструмент для редактирования файла заданий cron

Командой редактирования файла заданий cron является crontab -e

Linux Mint

В Linux Mint Вас может ожидать сюрприз, так как будет запущен редактор nano.


Может быть в этом редакторе и имеются преимущества, но лично меня он совершенно не устраивает. Поэтому воспользуюсь редактором, встроенным в Midnight Commander.

У Вас установлена такая, на мой взгляд, наиполезнейшая вещь? Если нет, то откройте терминал и введите команду sudo apt install mc.

EDITOR=mcedit crontab -e


Так как в дальнейшем вместо crontab -e вводить EDITOR=mcedit crontab -e затруднительно (забывается, понимаете ли), то включите в файловом менеджере отображение скрытых файлов, в файл .bashrc своего домашнего каталога внесите строку export EDITOR=mcedit и сохраните файл. Теперь при дальнейших вводах команды  crontab -e  у Вас будет запускаться  mcedit.


Runtu

В Runtu редактор nano в сборку не включён, а Midnight Commander наоборот – включён в комплект поставки. Поэтому здесь сюрприза не было. При вводе команды crontab -e система выдала запрос на выбор редактора:

Select an editor.  To change later, run 'select-editor'.
  1. /usr/bin/mcedit
  2. /usr/bin/vim.tiny

Choose 1-2 []:

При выборе 1 система запомнила мой выбор и больше вопросов не задавала.


К редактированию файла расписания запускаемых заданий вернёмся немного позже. А пока необходимо определить свои намерения. Так как если Вам по расписанию ничего запускать не требуется, то и дальнейшее чтение этой публикации не имеет практического смысла.


3. Что будет запускаться по расписанию?

По расписанию должен запускаться исполняемый файл, содержащий команду или последовательность команд. Этот файл может быть с расширением sh, т.е. скриптом, или не иметь никакого расширения. В любом случае он обязан быть исполняемым.

Примечание. 

На одном из форумов на заданный мной вопрос был получен следующий ответ: "Программа через cron запускается вне окружения рабочего стола, она не может просто так с ним взаимодействовать. И организовать это взаимодействие хоть в принципе и возможно, но довольно сложно – чтобы без глюков". 

Но, как будет показано далее, это возможно и касается варианта, в котором пользовательское задание cron запускается во время сеанса работы пользователя в системе, то есть пользователь взаимодействует с графическим окружением.

Следует определиться, если так можно выразиться, с процессом выполнения задания. Задание может быть выполнено или в фоновом режиме без какого-либо отображения на экране (по принципу "не видно и не слышно, но дело своё делает") или сопровождаться выводом на экран монитора. В случае запуска графических приложений, конечно, подходит только второе.

В этой публикации упор сделан на рассмотрении реализации задачи, которую можно описать тремя пунктами.

1. Ежедневный запуск Dropbox в выбранное время.
2. Ожидание определённое время, в течение которого производится синхронизация папок и файлов.
3. Остановка Dropbox.

Сформулированная задача может быть выполнена и в фоновом режиме, и с выводом на экран монитора, поэтому будут описаны оба варианта.

Условно реализацию работы в фоновом режиме назову "Вариант 1", а с выводом на экран монитора – "Вариант 2".

3.1. Вариант 1

Так как в варианте 1 взаимодействия с рабочим столом не предусматривается, то определяю перечень необходимых команд, записанных в файл daily-dropbox моего домашнего каталога.

Примечание. Как было отмечено выше, упомянутый файл можно оформить и как файл daily-dropbox.sh  Для системы разница в именах файла принципиального значения не имеет. Единственным требованием является то, что этот файл должен быть исполняемым. 

#!/bin/bash
dropbox start
sleep 15
rm /home/cemea/.config/autostart/dropbox.desktop
sleep 1200
dropbox stop

dropbox start – запуск dropboxd.

sleep 15 – пауза 15 секунд. Пауза необходима для того, чтобы запускаемый Dropbox "успел" создать ярлык автозапуска (что он в моей системе каждый раз делает). 15 секунд установлены экспериментально, так как при определённой степени загруженности системы Dropbox стартует не моментально.

rm /home/cemea/.config/autostart/dropbox.desktop – данная команда удаляет принудительно создаваемый в xfce ярлык запуска Dropbox при старте системы когда пользователь запускает Dropbox из меню программ (подробности).

sleep 1200 – пауза 1200 секунд, что соответствует 20-ти минутам (20х60). Предполагается, что этого времени будет достаточно, чтобы была осуществлена синхронизация каталога клиента Dropbox с облаком Dropbox.

Вы можете указать своё значение. Так как на ежедневной основе у меня в Dropbox помещаются небольшие объёмы данных, то отводимых на синхронизацию 20-ти минут мне хватает с избытком.

dropbox stop – остановка dropboxd. По этой команде Dropbox прекращает свою деятельность. Поэтому к данным большого объёма будет применяться правило "кто не успел, тот опоздал". Другими словами, их синхронизация будет продолжена в течение последующих сеансов работы Dropbox или завершена при ручном запуске клиента Dropbox.

Для подобных файлов у меня заведён специальный каталог Tools. Поэтому для своего удобства создаю в нём каталог cron и помещаю в него файл daily-dropbox. Далее в свойствах файла (секция "Права") ставлю галочку в поле "Разрешить запуск этого файла в качестве программы".

3.2. Вариант 2

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

zenity --info --text "Текст сообщения." 2>/dev/null --timeout=3

Поэтому в предыдущий текст будут добавлены такие команды. Вместо команды dropbox start будет использоваться dropbox start -i. Для моего графического окружения xfce принципиального значения между dropbox start и dropbox start -i нет, но в меню программ для запуска клиента Dropbox используется именно команда dropbox start -i.

Содержание исполняемого файла dropboxme.sh:

#!/bin/bash
zenity --info --text "Запуск клиента Dropbox." 2>/dev/null --timeout=3
dropbox start -i
sleep 15
rm /home/celesta/.config/autostart/dropbox.desktop
zenity --info --text "Автозапуск Dropbox удалён." 2>/dev/null --timeout=3
sleep 1200
zenity --info --text "Завершение работы Dropbox." 2>/dev/null --timeout=3
dropbox stop


4. Назначение пользовательского задания cron

Ввожу команду  crontab -e

Если посмотреть, что отображается в терминале, то можно увидеть такую запись:

no crontab for cemea - using an empty one

В запустившемся редакторе mcedit в новой строке пишу

15 22 * * * /home/cemea/Tools/cron/daily-dropbox

Что это означает?

Каждая задача формируется следующим образом:

минута  час  день  месяц  день_недели  команда

Соответственно, в диапазонах возможных цифр строка выглядит:

0 ... 59   0 ... 23   1 ... 31   1 ... 12   0 ... 7   команда


Поле "пользователь" присутствует только в таблицах /etc/crontab и др. расположенных в каталоге /etc/cron.d/.

Дополнительные варианты

Дефис (-) между целыми числами обозначает диапазон чисел. Например, 1-4 означает целые числа 1, 2, 3 и 4.

Список значений, разделённых запятыми, обозначает перечень. Например, перечисление 3, 4, 6, 8 означает четыре указанных целых числа.

Косая черта (/) используется для определения шага значений. Если после диапазона указать /<целое_число>. Например, значение минут 0-59/2, определяет, что задание будет запущено каждую вторую минуту.

Если вместо цифры введён символ *, то он соответствует "каждый/ую".

То есть, говоря проще, каждый день недели в 22 часа 15 минут будет запущена задача на синхронизацию Dropbox – /home/cemea/Tools/cron/daily-dropbox.

После ввода строки 15 22 * * * /home/cemea/Tools/cron/daily-dropbox нажимаю клавишу Enter, чтобы курсор перешёл на следующую строку. Если этого не сделать, то при попытке сохранения Вам будет выдано предупреждение:

new crontab file is missing newline before EOF, can't install.
Do you want to retry the same edit? (y/n)

При сохранении Вам будет выдан запрос


Пусть Вас не смущает предложение сохранить задание в каталог  /tmp  да ещё и под каким-то непонятным именем. Жмите "Сохранить".

Если в течение этого сеанса редактирования Вы не планируете вносить какие-либо изменения в свой crontab, то по F10 закрывайте mcedit.

Так как терминал у Вас ещё открыт, то Вы увидите, что в его окне появилось сообщение – crontab: installing new crontab

При назначении задания по варианту 2 строка моего задания имеет вид:

15 22 * * * export DISPLAY=:0 && /home/cemea/Tools/configs/dropboxme.sh

Это важно. Обратите внимание, что DISPLAY должно быть именно заглавными буквами. Если указать export display=:0, то на экране ничего не отобразится. Желающие получить теоретическое обоснование читают ветку форума.

Если поинтересоваться содержанием каталога /var/spool/cron/crontabs, то можно будет увидеть, что в нём появился файл c именем пользователя системы. В моём случае это файл cemea:


В этом файле и будут в дальнейшем находиться все пользовательские задания cron. Этих заданий может быть несколько. Применительно к рассматриваемой задаче внесу 2 задания. Первое будет запускать синхронизацию Dropbox c отображением его значка и всех информационных сообщений, а второе будет запускать синхронизацию Dropbox "тихо", не отвлекая меня от деятельности на благо общества. Например:

15 09 * * * export DISPLAY=:0 && /home/cemea/Tools/configs/dropboxme.sh
30 16 * * * /home/cemea/Tools/cron/daily-dropbox

Не забудьте, что после внесения второй записи необходимо добавить пустую строку (см. пояснение выше).

Для просмотра своих заданий используйте команду  crontab -l

Для удаления файла своих заданий используйте команду  crontab -r


5. Экспериментальная проверка

Как говорится, практика – критерий истины, поэтому проверим отработку назначенного задания.

Как было отмечено ранее, если при запуске заданий cron был использован вариант 1, то никакого взаимодействия с графическим окружением производиться не будет, поэтому запускаю диспетчер задач и вижу отработку своего здания cron.

Linux Mint



На рисунках звёздочками красного цвета отмечены выполняющиеся файл задания cron daily-dropbox, Dropbox (повторять длинную строку не буду), а также выполняемая на момент просмотра диспетчера задач команда speep 1200.

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


При повторном обращении к диспетчеру задач через 20 минут в списке выполняемых заданий перечисленные выше отсутствуют. Это свидетельствует о том, что задание cron было отработано и завершено.

Runtu

В Runtu вместо длинной строки dropbox-dist/... отображается просто dropbox, а вместо sleep 1200 только sleep. При имени исполняемого файла не daily-dropbox, а dropbox.sh будет отображён dropbox.sh


Выполнение заданий по варианту 2 (см. выше) Вы увидите на экране, хотя и через диспетчер задач они также будут отображаться.


6. А что ещё можно запускать?

Применяя инструкцию export DISPLAY=:0 && команда можно запланировать себе запуск желаемых графических приложений.

В частности, в какое-то время запустить браузер Firefox, в адресную строку которого автоматически будет вписан адрес ресурса, например, news.mail.ru  В этом случае содержание исполняемого файла будет следующим:

#!/bin/bash
firefox "http://news.mail.ru"

А в качестве прикола можно поставить себе напоминание:

#!/bin/bash
zenity --info --text "А не испить ли мне кофею?" 2>/dev/null --timeout=60

И вот сижу я, смотрю на экран, а мне вдруг выскакивает:


Поэтому здесь имеется простор для воплощения Ваших фантазий в наборы инструкций операционной системе. Главное – вводить правильные команды.

1 комментарий:

  1. спасибо за статью, очень доходчиво обьяснили

    ОтветитьУдалить