Вопрос или проблема
Как я могу выполнить команду shell в моем терминале, которая уведомит меня с помощью уведомления после истечения заданного времени?
Чтобы сделать это немного более конкретным, некоторые вещи, которые я ищу, это:
- Мне нужны только одноразовые уведомления, не повторяющиеся. Например, таймеры systemd имеют такую функциональность, но создание отдельного unit и таймера systemd каждый раз (а затем их удаление) было бы слишком непрактичным.
- Простая командная строка, чтобы я мог сделать что-то вроде
remindme "3 hours" "посмотри, закончилось ли дело x"
и не пришлось делать слишком много сложной shell-магии. Если это не будет возможно, то, по крайней мере, что-то, что можно обернуть в скрипт, было бы предпочтительнее. - Достаточно, если уведомление просто строка, предназначенная для меня, чтобы прочесть.
- Кроссплатформенность: оно должно как минимум работать на Linux и Mac.
- Уведомления не должны требовать от меня оставлять оболочку открытой.
- Если уведомление происходит через GUI, оно должно как минимум поддерживать Xorg и мак. Я предполагаю, что это будет что-то вроде balloon popup или диалогового окна; это должно поддерживать разные DE и не заставлять меня использовать Gnome, например.
- Если уведомление происходит через терминал, было бы хорошо, если бы оно работало как в TTY (без Xorg), так и в эмуляторе терминала под X.
- Уведомление не обязательно должно быть точным: например, если я установлю его на 1 час, а оно сработает через 63 минуты, это нормально.
- Мне не должно требоваться запускать команду для проверки уведомлений, так как я неизбежно забуду это сделать. Например, taskwarrior поддерживает различные задачи по времени, но я их не увижу, пока не выполню
task next
. - Оно не должно превышать мой временной лимит слишком сильно. Например, если я попытаюсь добавить команду
checkreminders
в мой bashrc, может пройти много времени, прежде чем я запущу новый терминал и увижу уведомления. То же самое относится к таким вещам, какalias ls=checkreminders && ls
. - Оно не должно зависеть от внешнего сервиса (например, веб-приложения или моего аккаунта gmail). Например, у Slack есть бот напоминаний, но я не хочу запускать Slack постоянно на каждом компьютере только ради уведомлений.
- Я предпочел бы минимальные зависимости, и чтобы мне не приходилось устанавливать кучу громоздких программ на каждый компьютер, где я хочу это использовать. Маленькие CLI-программы, которые широко доступны в менеджерах пакетов, в порядке, если они по умолчанию включены в большинство дистрибутивов Linux, тем лучше.
Использование: remindme -t "3m 1s" -m "Мне нужно сделать домашнее задание"
Время может быть просто числом, означающим секунду, или иметь суффикс s, m, h или d. См. страницу man для GNU sleep. Для macOS вам нужно преобразовать время в секунды или написать функцию для этого.
Решение 1: Использование wall. Работает на Linux, графически и не графически, должно работать на macOS, как минимум не графически.
#!/bin/bash
while getopts "t:m:" optname; do
case $optname in
t)
time=${OPTARG}
;;
m)
message=${OPTARG}
;;
esac
done
coproc (sleep $time && wall $message)
Решение 2.1: Уведомление на рабочем столе для Linux и Windows, требует notify-send
предоставляемое libnotify
#!/bin/bash
while getopts "t:m:" optname; do
case $optname in
t)
time=${OPTARG}
;;
m)
message=${OPTARG}
;;
esac
done
coproc (sleep $time && notify-send -a Reminder "$message")
Решение 2.2: Уведомление на рабочем столе для macOS. Не тестировалось.
#!/bin/bash
while getopts "t:m:" optname; do
case $optname in
t)
time=${OPTARG}
;;
m)
message=${OPTARG}
;;
esac
done
coproc (sleep $time && osascript -e 'display notification "$message" with title "Remainder"')
Ответ или решение
Вопрос о создании напоминаний через терминал может показаться сложной задачей, особенно с учетом необходимости кросс-платформенной поддержки и минимальных зависимостей от дополнительного программного обеспечения. Давайте рассмотрим, как можно решить эту проблему.
Теория
Для решения задачи, поставленной в вопросе, нам необходимо создать скрипт, который способен работать на различных операционных системах, таких как Linux и macOS, без существенных зависимостей от внешних сервисов. Скрипт должен позволять пользователю задать временной интервал и сообщение, а затем, через заданное время, показать уведомление пользователю. Основной задачей является предоставление решения, которое будет работать как в графическом окружении, так и в текстовом терминале.
Пример
Рассмотрим возможные реализации на языке Bash. Данные примеры используют встроенные возможности ОС и минимальные зависимости, такие как notify-send
и osascript
для отображения уведомлений. Ниже приведены примеры реализаций:
-
Использование wall для Linux и macOS (только текстовые уведомления):
#!/bin/bash while getopts "t:m:" optname; do case $optname in t) time=${OPTARG} ;; m) message=${OPTARG} ;; esac done coproc (sleep $time && wall $message)
Этот скрипт использует команду
wall
, чтобы отправить текстовое уведомление всем пользователям системы после истечения заданного времени. -
Использование notify-send для Linux:
#!/bin/bash while getopts "t:m:" optname; do case $optname in t) time=${OPTARG} ;; m) message=${OPTARG} ;; esac done coproc (sleep $time && notify-send -a Reminder "$message")
Здесь используется библиотека
libnotify
, предоставляющая утилитуnotify-send
для отправки графических уведомлений. -
Использование osascript для macOS:
#!/bin/bash while getopts "t:m:" optname; do case $optname in t) time=${OPTARG} ;; m) message=${OPTARG} ;; esac done coproc (sleep $time && osascript -e 'display notification "$message" with title "Reminder"')
В этом примере для отображения уведомлений используется командлет
osascript
.
Применение
Чтобы использовать скрипт, нужно сохранить один из приведенных выше примеров в файл, скажем, remindme.sh
, сделать его исполняемым с помощью команды chmod +x remindme.sh
, и вызывать его с нужными параметрами, например: ./remindme.sh -t "180m" -m "Проверьте завершение задачи X"
. Это позволит через три часа получить указанное уведомление.
Это решение минимально зависит от дополнительного софта, использует стандартные утилиты и предоставляет возможность кросс-платформенного использования, соответствуя всем указанным требованиям задачи.