Вступление

Иногда полезно получить визуальную обратную связь от скрипта. Например, когда завершается работа скрипта или задание cron, или, когда долгоиграющая сборка терпит неудачу. Или, когда во время выполнения скрипта возникает срочная проблема. 

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

Приведенный ниже код был написан и протестирован в Linux. А как насчет MacOS? Что ж ... это тоже можно сделать, приложив немного усилий. См. последнюю часть с некоторыми советами и подсказками.

Отправка уведомлений c терминала Linux

Чтобы отправлять уведомления c терминала Linux, используйте команду notify-send. Выполните команду which notify-send, чтобы проверить, присутствует ли она. Если нет, установите ее с помощью вашего менеджера пакетов, например:

sudo apt install notify-send

Несколько примеров простых уведомлений:

notify-send "Ужин готов!"
notify-send "Совет дня" "Как насчет дневного сна?"

Вы можете настроить уведомление с помощью таких параметров, как уровень срочности, настраиваемая иконка и т. д. Узнать больше о команде можно с помощью 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"

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

Совместите notify-send с командой AT

Все мы знаем cron используется для планирования команд через определенные промежутки времени. Команда at используется для планирования однократного выполнения команды в указанное время. Если вы запустите ее так:

at 12:00

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

К счастью, команда at принимает параметры со стандартного ввода, поэтому мы можем использовать ее следующим образом:

echo "npm run build" | at now + 1 minute
echo "backup-db" | at 13:00

Есть много способов указать время. От абсолютного времени, например, 10:00 до относительного времени, например, now + 2 hours, до специфичных моментов времени, таких как noon или midnight. Мы можем комбинировать это с notify-send⁣, чтобы отправить себе напоминания в будущее, например:

echo "notify-send 'Stop it and go home now?' 'Enough work for today.' -u critical" | at now

Команда REMIND 

Теперь давайте создадим настраиваемую команду bash для отправки себе напоминаний (REMIND). Как насчет чего-то столь простого и понятного, как:

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

Это лучше, чем Алекса! Как получить это добро?

См. код ниже. Он определяет вызываемую функцию shell 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

Хотя команды notify-send нет в MacOS, уведомления можно отправлять с помощью ActionScript. Например:

osascript -e 'display notification "Wake up!" with title "Reminder"'

Кроме того, имеется команда 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 не будет отправлять эти надоедливые уведомления, и точка. Это как-то связано с выполнением скрипта не в пользовательском пространстве. Вы можете найти дополнительную информацию и решение здесь: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard. И это помогает:

# 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

Уф. Надеюсь, это сработает и для вас, и вы также можете использовать напоминание скрипта на своем Mac! Удачного дня!

Disclaimer автора оригинальной статьи

Эта статья не рекламирует какие-либо из описанных продуктов, услуг или поставщиков. У нас нет никаких коммерческих интересов или ассоциаций с ними. Мы не пытаемся утверждать, что эти продукты или услуги подходят вам лучше всего, и не обещаем, что ваш опыт будет таким же. 

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

Комментарии (1)


  1. savostin
    11.12.2021 21:52

    А еще бы как-то получить уведомление из в MacOS терминала, подключенного к Linux... :)

    iTerm2 + shell_integration вроде как-то умел, но у меня под screen этот integration не работает. А с tmux как-то не сложились отношения...