Программирование

Полное руководство по 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, став участником.

использованная литература