2

I'm writing a python script that is run with sudo permissions. At some point, I would like to send a notification to the user. I have noticed that notify-send does not work as a root user, so I tried to run it as the actual user by doing su $SUDO_USER -c notify-send ..., but this does not work either.

The first of the following functions works when run without sudo privileges. None of them work when run with sudo. Any idea why?

def notify(message):

    subprocess.run(['notify-send', '-i', 'utilities-terminal', 'Notification Title', message],
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE,
                   check=True)


def notifySudo(message):

    subprocess.run(['su', os.environ['SUDO_USER'], '-c', 'notify-send', '-i', 'utilities-terminal', 'Notification Title', message],
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE,
                   check=True)
dvilela
  • 1,200
  • 12
  • 29
  • You must get the DISPLAY an XAUTHORITY user env var to print something on his screen. – ctac_ Feb 12 '19 at 16:50
  • @ctac_ I've tried `export DISPLAY=:0.0` (as seen in another posts) and also I've seen in some other questions this one `eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gdm-x-session)/environ)"` but it's not working yet. Could you give some more insight? – dvilela Feb 13 '19 at 23:51

1 Answers1

6

So after a bit of research, I've found the solution:

import os

def notify(title, message):

    userID = subprocess.run(['id', '-u', os.environ['SUDO_USER']],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            check=True).stdout.decode("utf-8").replace('\n', '')


    subprocess.run(['sudo', '-u', os.environ['SUDO_USER'], 'DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/{}/bus'.format(userID), 
                    'notify-send', '-i', 'utilities-terminal', title, message],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    check=True)
dvilela
  • 1,200
  • 12
  • 29