I'm trying to restart some programs (mail-notification and stalonetray) regularly, as they appear to die frequently. I want to set restart them whenever NetworkManager reconnects. Hence, I have them triggered by a script in /etc/NetworkManager/dispatcher.d/.


I can create a script as follows.

sudo -u foo_user pkill mail-notificati -x
sudo -u foo_user DISPLAY=:0 mail-notification &

This works fine if I run it directly as a user. However, if I call it from root's script, it fails. I am prompted to enter the passwords for mail-notification; it cannot read Gnome Keyring.

How can I run this program as foo_user in every way?

  • What does "in every way" mean? Every program that a user runs can have different environment, so saying that (for example) DISPLAY should be set for it to be "in every way" doesn't make much sense. You'd need to define this question more for it to make sense. – Chris Down Sep 29 '15 at 5:14
  • @ChrisDown I mean I want it to work when running the script as root as it does when running the script as foo_user. I appreciate that DISPLAY isn't necessarily relevant here, but included it as an example of what I was doing. – Sparhawk Sep 29 '15 at 5:16
  • That still doesn't clarify, because "doing the same thing when run as root as when run as a user" doesn't make sense -- an environment is per-process, not per-user. – Chris Down Sep 29 '15 at 5:17
  • @ChrisDown Sorry, I'm afraid I don't understand the distinction in this case. Here, I'm asking to run the mail-notification process as in foo_user's environment. – Sparhawk Sep 29 '15 at 5:18
  • How do you know foo_user is logged in, and on which display? On a single-user system it's perhaps reasonable to assume that it's always :0.0 but it is not reasonable to assume that the user is logged in at all times. Anyway, this makes more sense to run within the X session script of foo_user, which will remove both your original problem and the complications it caused you to want to try to solve. – tripleee Sep 29 '15 at 6:48

You can always use good old su :

man 1 su

This command opens a sub-shell as the user you want to impersonate. As root you can use it without being prompted for a password.

su foo_user -c whatevercommandyouwant

Works from scripts too.

  • I'm not sure what -x is (I get su: invalid option -- 'x'), but after removing that, it still fails as per the question. – Sparhawk Oct 2 '15 at 6:03
  • Hi, sorry for the confusion, but my aim is not to provide a one shot solution but to tell you how the command su works. If you did a direct cut and paste you may have got an error. But, that's exactly why I added a link to the su man page as the first thing. Please cut and paste this into the shell and see what it says ;) – runlevel0 Oct 5 '15 at 14:20
  • Sorry, I still don't understand. Are you suggesting that su will provide a different env to sudo that should fix my problem? If so, then that doesn't seem to be the case. – Sparhawk Oct 5 '15 at 21:57
  • Yes. Again: man7.org/linux/man-pages/man1/su.1.html " su allows to run commands with a substitute user and group ID. When called without arguments, su defaults to running an interactive shell as root. For backward compatibility, su defaults to not change the current directory and to only set the environment variables HOME and SHELL (plus USER and LOGNAME if the target user is not root). " anyway sudo has nothing to do with that, sudo su does. sudo grants permissions to run commands that require specific privileges to your user. – runlevel0 Oct 7 '15 at 8:19

If you want to interact with a GUI from a process that isn't started from that GUI, you need to set a few environment variables: at least DISPLAY, possibly also XAUTHORITY if it isn't in the default location, and for many modern programs you need to set DBUS_SESSION_BUS_ADDRESS.

But a more reliable approach for your problem would be to not restart those programs from NetworkManager. In addition to the difficulty of successfully launching them, you also need to worry about whether you're logged in at all, and if there might be other users and other displays to consider, and so on. Instead, kill those programs, but don't restart them. In your normal session, instead of starting them directly, start them from a supervisor that restarts them if they die. I think systemd includes this functionality (but I don't know how to use it); or you can use dedicated supervisor programs such as monit, supervise, …

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.