Как создавать пользовательские уведомления в Linux и Mac, напоминания на рабочем столе из терминала Linux.
Иногда полезно получать визуальную обратную связь от скрипта. Например, когда сценарий или задание cron завершается. Или когда не удается выполнить длительную сборку. Или при возникновении срочной проблемы во время выполнения скрипта. Настольные приложения могут делать это с помощью всплывающих уведомлений. Но это можно сделать и из сценария! Вы можете использовать команды сценария для отправки себе уведомлений и напоминаний.
Приведенный ниже код был написан и протестирован на Linux. А как насчет MacOS? Ну… это тоже можно сделать, приложив немного усилий. Некоторые подсказки и советы см. в последней главе.
Отправка уведомлений из терминала Linux
Чтобы отправить уведомление из терминала Linux, используйте команду notify-send. Выполните команду which at, чтобы проверить, присутствует ли она. Если нет, установите его с помощью выбранного вами менеджера пакетов, например
sudo apt install notify-send
Несколько примеров простых уведомлений:
notify-send "Dinner ready!" notify-send "Tip of the Day" "How about a nap?"
Вы можете настроить уведомление с помощью таких опций, как уровень срочности, пользовательский значок и т.д. Узнайте больше с помощью man notify-send. Вы можете использовать небольшой набор HTML-тегов в теле уведомления, чтобы придать вашим уведомлениям приятный внешний вид. Кроме того, URL отображаются как кликабельные, например:
notify-send -u critical \ "Build failed!" \ "There were <b>123</b> errors. Click here to see the results: http://buildserver/latest"
Отправленные уведомления обрабатываются средой рабочего стола и отображаются так же, как и любые другие уведомления. Они будут иметь одинаковый внешний вид, оформление и поведение.
Объедините уведомление-отправку с AT
Мы все знаем cron, используемый для планирования команд через регулярные промежутки времени. Команда at используется для планирования однократного выполнения команды в определенное время. Если вы запустите ее следующим образом:
at 12:00
Оно запустится в интерактивном режиме, где вы можете вводить команды для выполнения в заданное время. Это не очень удобно для скриптов. К счастью, at принимает параметры из стандартного ввода, поэтому мы можем использовать его таким образом:
echo "npm run build" | at now + 1 minute echo "backup-db" | at 13:00
Существует множество способов указания времени. От абсолютного времени, например 10:00, относительного времени, например сейчас + 2 часа, до особого времени, например полдень или полночь. Мы можем комбинировать его с notify-send, чтобы, например, показывать себе напоминания в определенное время в будущем:
echo "notify-send 'Stop it and go home now?' 'Enough work for today.' -u critical" | at now
Запланированные команды выполняются демоном под названием atd. В некоторых системах он не запущен по умолчанию. Вы можете использовать команду systemctl, чтобы включить демон и заставить его запускаться автоматически при перезагрузке системы:
sudo systemctl enable --now atd
Команда REMIND
Теперь давайте создадим пользовательскую команду bash для отправки себе напоминаний. Как насчет чего-то простого и удобного для человека, например:
remind "I'm still here" now remind "Time to wake up!" in 5 minutes remind "Dinner" in 1 hour remind "Take a break" at noon remind "It's Friday pints time!" at 17:00
Смотрите приведенный ниже код. Он определяет функцию оболочки под названием remind, которая поддерживает приведенный выше синтаксис. Фактическая работа выполняется в последних двух строках. Остальное отвечает за помощь, проверку параметров и т.д., что примерно соответствует соотношению полезного кода и необходимого белого шума в любом большом приложении 😉
Сохраните код где-нибудь, например, в файле ~/bin/remind и пропишите функцию в профиле .bashrc, чтобы она загружалась при входе в систему:
source ~/bin/remind
Перезагрузите терминал, затем введите remind, чтобы увидеть синтаксис. Наслаждайтесь!
#!/usr/bin/env bash function remind () { local COUNT="$#" local COMMAND="$1" local MESSAGE="$1" local OP="$2" shift 2 local WHEN="$@" # Display help if no parameters or help command if [[ $COUNT -eq 0 || "$COMMAND" == "help" || "$COMMAND" == "--help" || "$COMMAND" == "-h" ]]; then echo "COMMAND" echo " remind <message> <time>" echo " remind <command>" echo echo "DESCRIPTION" echo " Displays notification at specified time" echo echo "EXAMPLES" echo ' remind "Hi there" now' echo ' remind "Time to wake up" in 5 minutes' echo ' remind "Dinner" in 1 hour' echo ' remind "Take a break" at noon' echo ' remind "Are you ready?" at 13:00' echo ' remind list' echo ' remind clear' echo ' remind help' echo return fi # Check presence of AT command if ! which at >/dev/null; then echo "remind: AT utility is required but not installed on your system. Install it with your package manager of choice, for example 'sudo apt install at'." return fi # Run commands: list, clear if [[ $COUNT -eq 1 ]]; then if [[ "$COMMAND" == "list" ]]; then at -l elif [[ "$COMMAND" == "clear" ]]; then at -r $(atq | cut -f1) else echo "remind: unknown command $COMMAND. Type 'remind' without any parameters to see syntax." fi return fi # Determine time of notification if [[ "$OP" == "in" ]]; then local TIME="now + $WHEN" elif [[ "$OP" == "at" ]]; then local TIME="$WHEN" elif [[ "$OP" == "now" ]]; then local TIME="now" else echo "remind: invalid time operator $OP" return fi # Schedule the notification echo "notify-send '$MESSAGE' 'Reminder' -u critical" | at $TIME 2>/dev/null echo "Notification scheduled at $TIME" }
Уведомления с помощью сценариев в MacOS
Хотя в MacOS нет функции уведомления-отправки, уведомления можно отправлять с помощью ActionScript. Например:
osascript -e 'display notification "Wake up!" with title "Reminder"'
Полную документацию по команде display notification можно найти здесь. Кроме того, имеется at, так что все должно быть просто? А вот и нет. К сожалению, MacOS все больше усложняет использование своих возможностей для опытных пользователей…
Во-первых, команда at по умолчанию отключена. Даже если вы ее запустите, в запланированное время ничего не произойдет, потому что демон atrun отключен, и ни одной учетной записи пользователя по умолчанию не разрешено ее использовать.
Чтобы разрешить себе использовать команду, отредактируйте файл /var/at/at.allow и добавьте свое имя пользователя:
sudo open -a textedit /var/at/at.allow
Затем включите демон atrun:
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist
Давайте попробуем отправить уведомление:
osascript -e 'display notification "Wake up!" with title "Reminder"' | at now
… и ничего не происходит. Почему?
Демону не разрешено взаимодействовать с рабочим столом и ни с чем другим. Чтобы исправить это, зайдите в System Preferences / Security & Privacy / Privacy / Full Disk Access и добавьте atrun в список. Файл находится по пути /usr/libexec/atrun. Вы хотите видеть следующее:
… только как выбрать этот файл? MacOS не отображает системные папки в селекторе файлов, даже если минуту назад вам было предложено авторизоваться как администратор. Мне удалось обойти это, добавив папку /usr в список избранных папок в Finder:
И последнее, но не менее важное: для некоторых даже это не сработает. AT не будет посылать эти надоедливые уведомления, и точка. Это как-то связано с выполнением скрипта не в пространстве пользователя. Вы можете найти больше информации и решение здесь. Вот что помогает:
# Install reattach-to-user-namespace utility brew install reattach-to-user-namespace # Run notification command as follows reattach-to-user-namespace osascript -e 'display notification "Wake up!" with title "Reminder"' | at now
Надеюсь, у вас сработает уведомления в Linux и Mac, и вы сможете использовать скрипт напоминания remind на вашем Mac!
уведомления в Linux и Mac