3

I want to generate pop-ups for certain events in my python script. I am using 'notify-send' for that purpose.

subprocess.Popen(['notify-send', "Authentication", "True/False"])

The above command executes fine on terminal but when I run it from systemd-service it does not generate any pop-up.

When I see logs there are no errors.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
Wajahat
  • 107
  • 1
  • 2
  • 10

3 Answers3

2

You need to first set the environment variable so that the root can communicate with the currently logged user and send the notification in GUI.

In my case, I did it as follow:

[Unit]
Description=< write your description>
After=systemd-user-sessions.service,systemd-journald.service

[Service]
Type=simple
ExecStart=/bin/bash /<path to your script file>.sh
Restart=always
RestartSec=1
KillMode=process
IgnoreSIGPIPE=no
RemainAfterExit=yes
Environment="DISPLAY=:0" "XAUTHORITY=/home/<User name>/.Xauthority"

[Install]
WantedBy=multi-user.target

Here,

RemainAfterExit=yes

is very important to mention in service file.

make sure to change all the parameters like Description, User name and path to your script file.

also, make sure that script file has executable permission by executing the command

sudo chmod +x <path to your script file>.sh

Here my script file is written in bash which shows the notification by using the same 'notify-send' command.

Now here the Environment parameter is doing all the magic.

you can read more about this behavior and the problem discussed overhere.

I certainly don't know the complete working of these files or how this worked, but for me, it worked just fine.

So you can give it a try.

please let me know if this worked or not in your case.

Abhyam Gupta
  • 147
  • 4
  • 4
0

Running graphical applications requires the DISPLAY environment variable to be set, which would be set when run it from the CLI, but not when run from systemd (unless you explicitly set it).

This issue is covered more in Writing a systemd service that depends on XOrg.

I agree with the general advise that systemd may not be the best tool for the job. You may be better off using an "auto start" feature of your desktop environment to run your app, which would set the correct things in the environment that you need.

Mark Stosberg
  • 12,961
  • 6
  • 44
  • 49
  • I tried setting 'DISPLAY=:0' but no success. Someone suggested me to run the command by user (other than root) and it worked for me !! command = "DISPLAY=:0 notify-send Title Message" subprocess.Popen(['su', '-', 'wajahat', '-c', command]) Only problem now is that it does not work when I set user to root. Systemd-service runs my script as root and thus I am still stuck :( – Wajahat Apr 03 '18 at 08:01
  • You should have included your systemd file in the example. If you want to run the service as a user, use the`User=` directive in the `[Service]` section. – Mark Stosberg Apr 03 '18 at 14:30
  • My service require root privileges to perform some operations so I cannot change it. I need a way to generate pop-up from root. – Wajahat Apr 04 '18 at 06:43
  • Consider splitting your solution into two parts. The part that runs as root and the part that runs as the user. Root can send a message to socket when there's a notification to display. The user-service can listen on the socket and display the result. – Mark Stosberg Apr 04 '18 at 13:48
0

If running notify-send for desktop notifications in cron, notify-send is sending values to dbus. So it needs to tell dbus to connect to the right bus. The address can be found by examining DBUS_SESSION_BUS_ADDRESS environment variable and setting it to the same value.

Copy the value of DISPLAY and DBUS_SESSION_BUS_ADDRESS from your running environment and set them in [Service].Environment section

More info on the Arch Wiki: https://wiki.archlinux.org/index.php/Cron#Running_X.org_server-based_applications

Cirelli94
  • 1,714
  • 1
  • 15
  • 24