Pull to refresh

Кукушка на bash своими руками

Configuring Linux *
Sandbox
Привет, %username%.

Для организации моей работы удобно видеть или слышать уведомления о том, что прошел час, полчаса и т.д. Это нужно мне для ориентации во временном пространстве и правильного планирования своей работы.
Поскольку у меня стоит Ubuntu, то и статья будет про то, как сделать такие уведомления стандартными средствами Ubuntu.


Итак, мне нужно:
  • каждый час видеть и слышать уведомление о времени
  • уведомление не должно отвлекать
  • решение должно быть легким и экономным с точки зрения ресурсов

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

Уведомления в Ubuntu


Как известно, для уведомлений в Ubuntu применяется утилита notify-send. В последних версиях Ubuntu notify-send используется как основное средство уведомлений. Это действительно очень удобно, когда все сообщения показываются однообразно. Пользоваться ей так:
$ notify-send title message

Запустив эту несложную команду в консоли, вы через некоторое время увидите уведомление с заголовком title и сообщением message. У меня это выглядит так:
пример уведомления
Отлично, выводить сообщения мы уже умеем, осталось научиться показывать их по расписанию.

Задачи по расписанию в linux


Для задач по расписанию есть в linux отличное средство crontab
crontab -e

отрывается редактор, вбиваем в него строку:
0 */1 * * * DISPLAY=:0.0 notify-send "Часовщик" "Прошел 1 час"  

Сохраняем, любуемся результатом. Если хочется поиграться, то можно поставить уведомления раз в минуту, тогда отладочная запись будет выглядеть как-то так:
*/1 * * * * DISPLAY=:0.0 notify-send "Часовщик" "Прошла 1 минута"  

Теперь через равные промежутки времени мы можем что-нибудь выводить пользователю:
пример уведомления каждую минуту
Для пользователей, не умеющих настраивать crontab могу посоветовать online генератор. Например, такой.
Отмечу отдельно, что я не стал возиться с определением номера дисплея. Да, он может меняться, но за несколько месяцев работы у меня он не разу не поменялся, т.к. у меня все-таки десктоп, а скрипт все-таки сделан на коленке.
Поделюсь ещё одним рецептом. Пользоваться crontab -e не очень удобно, т.к. открывается редактор по умолчанию. Обычно это nano. По-моему он ужасен. Я обычно делаю так:

crontab -l > /tmp/crontab.file && cp /tmp/crontab.file /tmp/crontab.file.backup && gedit /tmp/crontab.file && crontab /tmp/crontab.file

Открывается файл в удобном gedit, редактируется, сохраняется или не сохраняется. После закрытия окна gedit настройки попадают в crontab.
Или оформляем все это дело в скрипт и кладем, например, на рабочий стол:

#!/bin/sh
#  _Nicolay
# file editCrontab.sh
crontab -l > /tmp/crontab.file && cp /tmp/crontab.file /tmp/crontab.file.backup && gedit /tmp/crontab.file && crontab /tmp/crontab.file
rm /tmp/crontab.file

Диалоги в скриптах linux


Теперь, частично проблема была решена. Но только частично, ведь я не всегда смотрю на экран монитора и могу пропустить сообщение. На помощь мне пришла утилита zenity. Она также уже была в системе. Пишем смело в crontab
0 */1 * * * DISPLAY=:0.0 zenity --info --title="Часовщик" --text="Прошел один час"

или отладочная запись:
*/1 * * * * DISPLAY=:0.0 zenity --info --title="Часовщик" --text="Прошла одна минута"

В итоге получилось что-то типа такого:
диалог:прошла одна минута
Какое-то время работать было удобно, но со временем окно-уведомление стало меня доставать. Этот факт заставил меня модернизировать свои крон-скрипты. В итоге я наткнулся на 3-ю полезную утилиту: ESpeak.
Она позволяет синтезировать речевые сообщения на разных языках.
Добавляем новую строчку в crontab:
0 */1 * * * espeak  -vru -s130 "прошел 1 час"

или отладочная строка
*/5 * * * * espeak  -vru -s130 "прошло 5 минут"

В итоге, вот что получилось


Синтезатор речи по-русски говорил ужасно. Слушать было противно, и поэтому я переключился на английский и сделал ещё ряд доработок:
  • заставил часовщика говорить ещё и время
  • добавил напоминания о том, что нужно попить кофе.

Конечный функционал уведомлений меня полностью устроил. Мне не пришлось ничего ставить, все было легковесным и надежным.
Мой файл crontab сейчас выглядит так:

# crontab file
#  _Nicolay
#  ежечасные уведомления о времени
0 */1 * * * /usr/local/scripts/hours.sh
# уведомления о кофе
23 12,16 * * * DISPLAY=:0.0 zenity --info --title="Уведомление" --text="пора бы кофейку!!!"

А файл hours.sh:

#!/bin/sh
# hours.sh
#  _Nicolay
DISPLAY=:0.0 notify-send "часовщик" "`date +%k` часов"
espeak  -ven -s130 "`date +%l` hours"

Я вынес скрипты в файл hours.sh из-за того, что crontab скрипт не поддерживает обработку машинописного обратного апострофа. Если же вы в crontab укажете машинописный обратный апостроф, то скрипт в указанное время не сработает.

Ну и под конец скрины того, как это выглядит у меня.

Каждый час выводится сообщение сколько времени:
23 часа
Сообщение дублируется звуком. Если я рядом с компьютером, я его услышу. И два раза в день мне отправляется напоминание о том, что нужно все-таки передохнуть.


UPD: Доработал скрипт на основе советов и комментариев.

Отдельное спасибо lionsimba за комментарий про festival.

В итоге, получилась новая версия hours.sh:

#!/bin/sh
# hours.sh
#  _Nicolay
#HOURS="`date +%l`"
HOURS="`date +%k`"

HOURS_TXT="Сколько времени?"
HOURS_TXT_SAY=$HOURS_TXT


if [ "$HOURS" -eq 11 ]; then
    HOURS_TXT="$HOURS часов"
    HOURS_TXT_SAY="$HOURS часов"
elif [ "$HOURS" -eq 12 ]; then
    HOURS_TXT="$HOURS часов"
    HOURS_TXT_SAY="$HOURS часов"
elif [ "$HOURS" -eq 13 ]; then
    HOURS_TXT="$HOURS часов"
    HOURS_TXT_SAY="$HOURS часов"
elif [ "$HOURS" -eq 14 ]; then
    HOURS_TXT="$HOURS часов"
    HOURS_TXT_SAY="$HOURS часов"
elif [ "$(($HOURS % 10))" -eq 0 ]; then
    HOURS_TXT="$HOURS часов"
    HOURS_TXT_SAY="$HOURS часов"
elif [ "$(($HOURS % 10))" -eq 1 ]; then
    HOURS_TXT="$HOURS час"
    HOURS_TXT_SAY="$HOURS час"
elif [ $(($HOURS % 10)) -lt 5 ]; then
    HOURS_TXT="$HOURS часа"
    HOURS_TXT_SAY="$HOURS часаa"
else
    HOURS_TXT="$HOURS часов"
    HOURS_TXT_SAY="$HOURS часов"
fi

DISPLAY=:0.0 notify-send -i "typing-monitor" "Часовщик" "$HOURS_TXT"
#espeak  -ven -s130 "`date +%l` hours"
echo "$HOURS_TXT_SAY" | festival --tts --language russian


Скрипт вполне сносно сообщает по-русски о времени.

На этом всё, спасибо за внимание.
Tags:
Hubs:
Total votes 47: ↑40 and ↓7 +33
Views 23K
Comments Comments 44