Заставляем работать связку: python, notify2, crontab


Опубликовано 2015.03.12


При реализации скрипта автоматической загрузки новых подкастов с сайта podfm.ru возникла необходимость внедрения уведомлений на рабочем столе о появлении новых файлов. Для решения этой задачи была выбрана библиотека notify2. И все работало хорошо, до тех пор, пока не потребовалось запускать скрипт по расписанию в crontab…

Ниже приведен код скрипта, который позволяет вывести уведомление на рабочий стол:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import notify2

notify2.init("podfmdog")
notify = notify2.Notification("Title", "Message")
notify.show()                  
Результат работы скрипта.

При попытке запустить этот скрипт в crontab появляется сообщении об ошибке:

Traceback (most recent call last):
  File "<PATH>/my1.py", line 5, in <module>
    notify2.init("podfmdog")
  File "/usr/lib/python3/dist-packages/notify2.py", line 93, in init
    bus = dbus.SessionBus(mainloop=mainloop)
  File "/usr/lib/python3/dist-packages/dbus/_dbus.py", line 211, in __new__
    mainloop=mainloop)
  File "/usr/lib/python3/dist-packages/dbus/_dbus.py", line 100, in __new__
    bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
  File "/usr/lib/python3/dist-packages/dbus/bus.py", line 122, in __new__
    bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11

Проблема заключается в том, что notify2 необходимо знать адрес пользовательской шины dbus. Для этого перед запуском скрипта нам необходимо экспортировать переменную окружения DBUS_SESSION_BUS_ADDRESS. Сделать это можно следующим образом:

...
USERNAME=`whoami`
...
export DBUS_SESSION_BUS_ADDRESS=`ps -u $USERNAME e | grep -Eo 'dbus-daemon.*address=unix:abstract=/tmp/dbus-[A-Za-z0-9]{10}' | tail -c35`
...

Полный код скрипта можно взять здесь. Следует отметить, что скрипт должен вызываться из crontab от имени пользователя с активной сессией x11.