Программирование
Полное руководство по Cron и Launchd в macOS / Linux
Пошаговое руководство по планированию задач
Table of contents Introduction 1. Papermill and terminal-notifier 2. cron for Linux/macOS 3. launchd for macOS Conclusion
[Обновление 1: 2021–05–28]
Введение
У вас есть проект Data Science, который требует вашего времени каждый день? Вы используете каналы данных, которые обновляются ежедневно? Например, Репозиторий данных о новом коронавирусе COVID-19 (2019-nCoV) 2019 года от Johns Hopkins CSSE обновляется ежедневно, и я использую его в своем личном проекте.
Вручную я запускаю Jupyter, открываю проект, перезапускаю ядро и запускаю все ячейки, затем git add / commit / push. Это немного работы. В этой статье я расскажу о пошаговом процессе создания launchd
и cron
заданий для вашего проекта по науке о данных, чтобы он автоматически обновлял ваш проект в фоновом режиме и даже уведомлял вас.
cron
для Linux / macOS и launched
для macOS
Хотя launchd является предпочтительным методом в macOS, метод
cron
по-прежнему работает и в macOS.
cron
- это утилита Linux, которая планирует автоматический запуск команды или сценария на вашем сервере / компьютере в указанное время и дату. Задание cron - это запланированная задача, и она очень полезна для автоматизации повторяющихся задач.
launchd создан Apple и заменяет множество инструментов Unix, таких как cron
, inetd
, init
, и т. д..
Вы можете начать планировать задачи и сэкономить много своего драгоценного времени после прочтения этой статьи.
Шаг 0: бумажная фабрика и терминал-уведомитель
Бумажная фабрика
Papermill - это инструмент для параметризации и запуска Jupyter Notebooks. Я могу использовать это для запуска файла Jupyter Notebook в файле cron и launchd.
$ pip install papermill
or
$ pip3 install papermill
$ papermill --help
Вы можете найти справку по интерфейсу командной строки здесь.
Использование бумажной фабрики:
papermill [OPTIONS] NOTEBOOK_PATH OUTPUT_PATH
Я скоро покажу вам пример.
терминал-уведомитель
Terminal-notifier - это инструмент командной строки для отправки уведомлений пользователей macOS. Я буду использовать это, чтобы уведомить меня, когда запланированное задание будет выполнено.
Установить терминал-уведомитель.
$ brew install terminal-notifier
$ terminal-notifier -help
cron для Linux / macOS
В macOS вы можете запускать фоновое задание по расписанию двумя способами: запускаемые задания и задания cron. Обратите внимание, что оно по-прежнему поддерживается в macOS v10.15, хотя cron
не является рекомендуемым решением, а launchd
был заменен.
Шаг 1. Настройка задания cron
Вы можете настроить задание cron, используя свое имя пользователя:
$ whoami your-name
$ sudo crontab -u your-name -e Password: sh-3.2#
Вы можете включить пользователя root, используя sudo su
в macOS, так что вам не нужен пароль.
$ sudo su
$ crontab -u your-name -e
-u
указывает имя пользователя. -e
редактирует текущий crontab.
Синтаксис
Добавьте пять чисел, как описано выше, и путь к файлу, который хотите запустить.
Пример:
0 10 * * * ~/DataScience/covid-19-stats/covid19-cron
Вышеупомянутый файл будет запускаться ~/DataScience/covid-19-stats/covid19-cron
каждый день в 10:00.
Если система выключена или находится в спящем режиме, задания cron не выполняются. Если вы пропустите назначенное время, оно будет выполнено в следующее назначенное время, когда ваша система будет включена.
Вы можете вывести stdout
и stderr
:
# log stdout and stderr
42 6 * * * ~/DataScience/covid-19-stats/covid19-cron > /tmp/stdout.log 2> /tmp/stderr.log
>
перенаправить стандартный вывод на /tmp/stdout.log
и >2
перенаправить стандартную ошибку на /tmp/stderr.log
.
После того, как вы настроили задание cron, вы можете его перечислить:
$ crontab -l
0 20 * * * ~/DataScience/covid-19-stats/covid19-cron
Если вы хотите удалить все задания cron:
$ crontab -r
Вы можете добавить несколько заданий cron в crontab.
0 20 * * * ~/DataScience/covid-19-stats/covid19-cron
0 7 * * * Path/to/file/to/execute
0 7 * * 0 Path/to/another/file/to/execute
Crontab guru - это быстрый и простой инструмент для создания расписания cron.
Шаг 2: написание cron-задания
Вы можете поместить все файлы заданий cron в каталог, но я помещаю его в корень проекта. Измените текущий рабочий каталог на свой проект, создайте файл задания cron и откройте его в редакторе. Исполняемые файлы не должны иметь .sh
расширения согласно руководствам по стилю Google.
$ cd path/to/project
$ touch covid19-cron
$ vim covid19-cron
Шаг 3. Определите shebang
Шебанг, используемый в первой строке скриптов, указывает операционную систему UNIX / Linux для выполнения.
Несмотря на то, что Papermill и терминал-уведомитель работают в терминале, нам нужно добавить их пути.
Давай найдем их.
$ which papermill /usr/local/bin/papermill
$ which terminal-notifier /usr/local/bin/terminal-notifier
В моем файле covid19-cron:
#!/usr/bin/env bash # run covid-19 files # git add, comit and push dir=/Users/shinokada/DataScience/covid-19-stats papermill=/usr/local/bin/papermill notifier=/usr/local/bin/terminal-notifier cd $dir $papermill covid-19-matplotlib.ipynb ./latest/covid-19-matplotlib.ipynb # more files ... $papermill covid-19-plotly.ipynb ./latest/covid-19-plotly.ipynb
git add . git commit -m "update" git push $notifier -title Covid19 -subtitle "Daily Updated" -message "Completed" -open "https://mybinder.org/v2/gh/shinokada/covid-19-stats/master" now=$(date) echo "Cron job update completed at $now"
Я создаю «последний» каталог в корневом каталоге. Papermill выводит файлы в этот «последний» каталог. Поскольку мы собираемся использовать git, вам нужно убедиться, что у вас есть .git
в корне проекта.
Если вы используете %run somefile
, я предлагаю вам добавить их в cron-файл.
Я использую title
, substitle
, message
и open
для опций терминала-уведомителя.
Краткое руководство по терминалу-уведомителю
Шаг 4: Добавьте разрешение на выполнение
Этому файлу bash требуется разрешение на выполнение.
$ chmod u+x covid19-cron
chmod
устанавливает права доступа к файлам.
chmod u+x covid19-cron
позволяет пользователю запускать covid19-cron.
Приведенная выше команда такая же, как:
$ chmod 744 covid19-cron
Шаг 5 Почта
Ваш терминал отправляет свой вывод и сообщения об ошибках по почте после выполнения задания cron. Давайте проверим, сработало ли задание cron.
$ mail
Вам нужно нажать Enter, чтобы прочитать сообщения, а затем q и Enter, чтобы выйти. Используйте j
, чтобы увидеть следующие строки. Вам нужно проверить, нет ли в почте ошибок. В случае ошибок нужно озаботиться проблемой.
Шаг 6 Тестирование работы cron
Вам нужно сбросить время crontab, чтобы проверить свою работу cron. launchd
позволяет нам протестировать работу, но для cron
это единственный способ проверить.
$ sudo crontab -u your-name -e
# change time 5 20 * * * ~/DataScience/covid-19-stats/covid19-cron $ crontab -l 5 20 * * * ~/DataScience/covid-19-stats/covid19-cron
Когда тест будет завершен, отобразится уведомление.
launchd для macOS
launchd
- это унифицированная среда управления службами с открытым исходным кодом для запуска, остановки и управления демонами, приложениями, процессами и сценариями.
Если вы планируете запуск задания, задав ключ StartCalendarInterval, а компьютер находится в спящем режиме, когда задание должно было быть выполнено, ваше задание будет выполнено, когда компьютер проснется.
Однако, если компьютер выключен, когда задание должно было быть выполнено, задание не будет выполнено до следующего назначенного времени.
Шаг 1: файл plist
Файл PLIST - это общесистемный файл конфигурации демона / агента для каждого пользователя. Демон / агент - это программа, работающая в фоновом режиме без ввода данных пользователем. Вы определяете имя программы, когда вы ее запускаете, что вы хотите запускать и т. Д. Вы сохраняете все свои файлы plist в ~/Library/LaunchAgents
directory.
[Update.1] Если у вас нет ~/Library/LaunchAgents
, вам нужно его создать.
# check ~/Library if it has LaunchAgents
$ ls ~/Library
# if not create the directory
$ mkdir ~/Library/LaunchAgents
Создайте plist
файл:
$ cd ~/Library/LaunchAgents
$ touch com.shinokada.covid19.plist
В com.shinokada.covid19.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.shinokada.covid19</string>
<key>Program</key>
<string>/Users/shinokada/DataScience/covid-19-stats/covid19-launchd</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/bin:/usr/bin:/usr/local/bin</string>
</dict>
<key>StandardInPath</key>
<string>/tmp/covid.stdin</string>
<key>StandardOutPath</key>
<string>/tmp/covid.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/covid.stderr</string>
<key>WorkingDirectory</key>
<string>/Users/shinokada/DataScience/covid-19-stats</string>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>8</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
Здесь я запускаю /Users/shinokada/DataScience/covid-19-stats/covid19-launchd
в 8:00 каждый день.
Краткое руководство по настройке в файле plist
Шаг 2: Создание файла bash
Создайте файл с именем covid19-launchd в корневом каталоге проекта. Это очень похоже на приведенное выше covid19-cron
.
#!/usr/bin/env bash # run covid-19 files # git add, comit and push papermill covid-19-data.ipynb ./latest/covid-19-data.ipynb papermill multiplot.ipynb ./latest/multiplot.ipynb # more files ... papermill uk-japan.ipynb ./latest/uk-japan.ipynb papermill Dropdown-interactive.ipynb ./latest/Dropdown-interactive.ipynb git add . git commit -m "update" git push terminal-notifier -title Covid19 -subtitle "Daily Updated" -message "Completed" -open "https://mybinder.org/v2/gh/shinokada/covid-19-stats/master" now=$(date) echo "launchd update completed at $now"
Поскольку мы устанавливаем PATH EnvironmentVariables
в файле plist, нам не нужно беспокоиться об абсолютных путях Papermill и терминала-уведомителя.
Вы можете проверить, работает ли он с помощью bash covid19-launchd
.
Шаг 3. Добавьте разрешение на выполнение
Этому файлу bash требуется разрешение на выполнение.
$ chmod u+x covid19-cron
Шаг 4. Тестирование launchd
lauchctl
управляет процессом запуска macOS. В нем есть такие подкоманды, как list
, start
, stop
, load
, unload
, и т. Д..
В моем случае;
$ launchctl list | grep covid - 0 com.shinokada.covid19
# test/debug $ launchctl start com.shinokada.covid19
# if you need to stop $ launchctl stop com.shinokada.covid19
# load the job $ launchctl load ~/Library/LaunchAgents/com.shinokada.covid19.plist
# unload the job $ launchctl unload ~/Library/LaunchAgents/com.shinokada.covid19.plist
# get help $ launchctl help
Перезагрузка
launchctl
не имеет команды перезагрузки для чтения изменений в файле config.plist. Вместо этого вы должны выгрузить, а затем загрузить файл plist заново, например:
$ launchctl unload ~/Library/LaunchAgents/com.shinokada.covid19.plist
$ launchctl load $_
$_
, как и !$
, относится к последнему аргументу предыдущей команды.
Если вы вносите какие-либо изменения в скрипт или файл plist, убедитесь, что вы выгрузили и загрузили файл plist.
Краткое руководство по запуску
launchctl
имеет много подкоманд, и на следующей диаграмме показаны важные из них.
Вывод
Запланированные задачи экономят ваше время и просты в настройке. Вы можете настроить его не только для своих проектов в области науки о данных, но и для повседневной работы, такой как обновление пакетов узлов, формул домашнего приготовления и т. Д. Если вы экономите 3 минуты в день, это сэкономит более 18 часов год! Если вам интересно, вы можете увидеть мой образец проекта здесь.
Новостная рассылка
Получите полный доступ ко всем статьям на Medium, став участником.
использованная литература
- Https://apple.stackexchange.com/questions/29056/launchctl-difference-between-load-and-start-unload-and-stop
- Https://www.launchd.info/