I need to run a script as root called root.py. I need to create notifications within the script. I made a separate script specifically for the notifications called notify.py.

Here is notify.py:

import pynotify
import sys

def notify(title, message):
    n = pynotify.Notification (title,

if __name__ == '__main__':
    notify(sys.argv[1], sys.argv[2])

notify.py script works well with a user not as root:

python notify.py Title Message

But I need to call this script inside root.py, which is ran as root. It fails if I run it as root. So, I tried to for lack of better words, sign out as root by launching it as another user (I also replaced sudo with gksudo in the following):

xhost local:user
gksudo -u user notify.py Title Message

Won't work.

Any ideas?

btw: I had a similar problem with running gtk from root ran upstart scripts. Also, gvfs won't change attributes as root when as other user as sudo.


4 Answers 4


sux - wrapper around su which will transfer your X credentials http://fgouget.free.fr/sux/

$ sudo apt-get install sux
  • Is there official X credential documentation? I would like to look over just sux would be adjusting.
    – bambuntu
    Mar 18, 2012 at 21:54
  • sux is a readable shell script. Install it [sudo apt-get install sux], find its location [which sux], view it [cat $(which sux)]. If you don't like it remove it [sudo apt-get purge sux]
    – jippie
    Mar 18, 2012 at 22:19
  • Ok, but I will have to try later because I can't download now.
    – bambuntu
    Mar 21, 2012 at 21:38
  • BTW you sux from unprivileged user to root and then execute the root.py script.
    – jippie
    Mar 21, 2012 at 22:28

Direct copy and paste:

You won't be able to open a server on port 80 without root privileges, this is a restriction on the OS level. So the only solution is to drop root privileges after you have opened the port.

Here is a possible solution to drop root privileges in Python: Dropping privileges in Python. This is a good solution in general, but you'll also have to add os.setgroups([]) to the function to ensure that the group membership of the root user is not retained.

I copied and cleaned up the code a little bit, and removed logging and the exception handlers so it is left up to you to handle OSError properly (it will be thrown when the process is not allowed to switch its effective UID or GID):

import os, pwd, grp

def drop_privileges(uid_name='nobody', gid_name='nogroup'):
    if os.getuid() != 0:
        # We're not root so, like, whatever dude

    # Get the uid/gid from the name
    running_uid = pwd.getpwnam(uid_name).pw_uid
    running_gid = grp.getgrnam(gid_name).gr_gid

    # Remove group privileges

    # Try setting the new uid/gid

    # Ensure a very conservative umask
    old_umask = os.umask(077)

from here.

If you MUST regain root priviledges there's always policykit.

  • This sounds like process that just needs to be started once, like a server, in which you mention. Is this really something that I can apply to a process that needs to periodically act as root? Not all things in my script are necessary as root, but some are. I'm a little unsure after dropping privileges in the parts that don't need root, how I would elevate when root was needed, since now the script would not be root id.
    – bambuntu
    Mar 18, 2012 at 22:02
  • you would launch separate processes and drop privs for those. just how i would go about it. like only return when you need more privs...but I get creative about using blocking as a tool instead of a reason to use threading. Mar 18, 2012 at 22:09
  • It sounds like the main process that spawns process needs to stay as root. Each process that it spawns should have appropriate privileges set. If I got that wrong, let me know.
    – bambuntu
    Mar 20, 2012 at 0:21
  • Exactly so. Doing it any other way is just silly. If something bad happens and someone gets arbitrary execution, you're basing your execution...with the ability to regain privs...on bad data. Mar 20, 2012 at 0:30

This is a wild shot, please downvote it if it's wrong. Please next time, if possible, add the relevant error messages.

Maybe the root user just lacks a display to do GUI operations. Have you tried:

DISPLAY=:0 python notify.py Title Message

as root?.

  • I tried that, but it doesn't take it as in my python subprocess.call(commandArgList) I tried the script in a root shell by itself and it worked. But won't work in my upstart script.
    – bambuntu
    Mar 21, 2012 at 21:37
  • Arguably, something that needs to interact with the GUI shouldn't be a upstart script. Myself, I will make a daemon that has to inform about something send a dbus message, then I would build a client (or clients, one for KDE, one for gnome, one command line) to listen to dbus for the message and notify the user. Note that a upstart script should work even with no user logged. That way I also has better security, as client part is not running as root, and I have the ability to notify multiple users, each one running it's own client. Mar 22, 2012 at 8:27

as root, launch :

export `dbus-launch` 

and run your notify program

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.