У меня есть следующий сценарий Python:
# /path/to/__main.py__
[..]
subprocess.call("DISPLAY=:0 dbus-launch /usr/bin/notify-send -i dialog-information \'foo\' \'bar\'", shell=True)
[..]
и следующий .service файл:
# /etc/systemd/system/notification.service
[Unit]
Description=Notification service
[Service]
# Run permission service
ExecStart=/usr/bin/python3 /path/to/__main__.py
# keep process after user logs off
RemainAfterExit=false
[Install]
WantedBy=default.target
Когда я звоню /usr/bin/python3 /path/to/__main__.py
в моем терминале появляется всплывающее окно и нет никакого замораживания или чего-либо.
Однако, когда я звоню sudo systemctl restart notification.service
, система (UI) замораживания для ~20s (никакие взаимодействия, возможные в UI), затем, всплывающее окно появляется.
Вопрос: Почему эта проблема происходит только, когда сценарий называют через systemd сервис?
Дальнейшие выводы (возможно, полезный для расследования)
Это - вывод sudo systemctl status notification.service
:
user@host:~$ sudo systemctl status notification.service
● notification.service - Notification service
Loaded: loaded (/etc/systemd/system/notification.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2019-12-13 11:54:37 +08; 1h 41min ago
Process: 18420 ExecStartPre=/bin/bash -c test $(/usr/bin/id -u) -eq 0 (code=exited, status=0/SUCCESS)
Main PID: 18433 (python3)
Tasks: 25 (limit: 4915)
CGroup: /system.slicenotification.service
├─18433 /usr/bin/python3 /path/to/__main__.py
├─18583 /usr/bin/dbus-daemon --syslog --fork --print-pid 5 --print-address 7 --session
├─18588 /usr/lib/x86_64-linux-gnu/notify-osd
├─18715 /usr/lib/gvfs/gvfsd
├─18822 /usr/bin/dbus-daemon --syslog --fork --print-pid 5 --print-address 7 --session
├─18827 /usr/lib/x86_64-linux-gnu/notify-osd
├─18990 /usr/lib/gvfs/gvfsd
├─19055 /usr/bin/dbus-daemon --syslog --fork --print-pid 5 --print-address 7 --session
├─19059 /usr/lib/x86_64-linux-gnu/notify-osd
└─19222 /usr/lib/gvfs/gvfsd
Dec 13 11:55:34 host notify-osd[18827]: dnd_is_screensaver_active(): Got error "The name org.gnome.ScreenSaver was not provided by any .service files"
Dec 13 11:55:34 host notify-osd[18827]: dnd_is_idle_inhibited(): got error "The name org.gnome.SessionManager was not provided by any .service files"
Dec 13 11:55:43 host dbus-daemon[19055]: [session uid=0 pid=19053] AppArmor D-Bus mediation is enabled
Dec 13 11:55:43 host dbus-daemon[19055]: [session uid=0 pid=19053] Activating service name='org.freedesktop.Notifications' requested by ':1.0' (uid=0 pid=19001 comm="/usr/bin/notify-send -i dialog-information UpdateR" label="unconfined")
Dec 13 11:56:01 host dbus-daemon[19055]: [session uid=0 pid=19053] Activating service name='org.gtk.vfs.Daemon' requested by ':1.1' (uid=0 pid=19059 comm="/usr/lib/x86_64-linux-gnu/notify-osd " label="unconfined")
Dec 13 11:56:01 host dbus-daemon[19055]: [session uid=0 pid=19053] Successfully activated service 'org.gtk.vfs.Daemon'
Dec 13 11:56:01 host org.gtk.vfs.Daemon[19055]: fuse: bad mount point `/root/.gvfs': Transport endpoint is not connected
Dec 13 11:56:01 host dbus-daemon[19055]: [session uid=0 pid=19053] Successfully activated service 'org.freedesktop.Notifications'
Dec 13 11:56:01 host notify-osd[19059]: dnd_is_screensaver_active(): Got error "The name org.gnome.ScreenSaver was not provided by any .service files"
Dec 13 11:56:01 host notify-osd[19059]: dnd_is_idle_inhibited(): got error "The name org.gnome.SessionManager was not provided by any .service files"
lines 1-28/28 (END)
Хорошо, вот то, что я сделал для решения этой проблемы при запущении скриптов из crontab корня. Я все еще изучаю Python, таким образом, необходимо будет преобразовать эту информацию как требуется.
Первый, я добавил xhost полномочия для корня к моему .bashrc:
xhost + SI:localuser:root > /dev/null
115-секундный, я добавил следующие переменные к crontab корня:
DISPLAY=":0.0"
XAUTHORITY="/home/me/.Xauthority"
XDG_RUNTIME_DIR="/run/user/1000"
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
В-третьих, я работал, каждый уведомляет - отправляют как я, что-то вроде этого:
su me -c '/usr/bin/notify-send "Weekly backup started - $(date +%Y-%m-%d) @ $(date +%H:%M:%S)"'