What is XDG_RUNTIME_DIR?

While I was trying to open Evince from Command line, it's giving me an error

neo@Muhammad:~$ sudo evince

No protocol specified

** (evince:4164): WARNING **: Could not open X display
No protocol specified
error: XDG_RUNTIME_DIR not set in the environment.
Cannot parse arguments: Cannot open display:

How to troubleshoot this problem ?


First things first: XDG_RUNTIME_DIR

To answer your first question, "What is XDG_RUNTIME_DIR?", it is an environment variable that is set automatically when you log in. It tells any program you run where to find a user-specific directory in which it can store small temporary files. Note that XDG_RUNTIME_DIR is set by pam_systemd(8), so it is not actually related to X (running programs graphically), which is the problem you seem to be having.

How to troubleshoot

Your second question, "How to troubleshoot this problem?" is a very good one. That means you're interested in not only what the fix is, but also how to figure it out on your own. To start, look at the first error messages first. In particular, searching for No protocol specified or WARNING **: Could not open X display, should show you that the problem is with X (also called The X Windowing System) which is how graphical programs are shown on your screen. Knowing that should raise many troubleshooting questions in your mind.

X DISPLAY

Your next question might be, what is this "X display" that evince can't open? A "display" is the address for your screen.[*] Any program that wants to write to your screen has to know the address. You can see what your X display is by checking the DISPLAY environment variable:

echo $DISPLAY

And you can check what sudo thinks your DISPLAY is by typing:

sudo -s
echo $DISPLAY
exit

If it doesn't show anything, then that's the problem. (See fix below).

XAUTHORITY

But, what if that's not the problem and the DISPLAY is set correctly in sudo? Then you might wonder, does X have some sort of permissions that prevent other users from writing on my display? If you thought that, you'd be right, X has two main authorization methods: xauth and xhost. The most commonly used one today is xauth(1) which uses the XAUTHORITY environment variable. Again, let's check if it is properly set in sudo:

echo $XAUTHORITY
sudo -s
echo $XAUTHORITY
exit

If XAUTHORITY is pointing to a file in your home directory for you, but it's blank when you run sudo, then that's the problem.

FIX: Save the Environment Variables

So, what's the fix? If either the DISPLAY or the XAUTHORITY environment variables aren't getting saved across the sudo, you can tell sudo(8) to preserve the environment by using the -E option, like so:

sudo -E evince

A better way: env_keep

You might well ask, Wait, if -E makes everything magically work, then why isn't it the default for sudo? The answer is that it is a potential security hazard. Environment variables affect the way programs work and you don't want them all being exported from a user account to the root. The "correct" way to do it is to add the line Defaults env_keep += "DISPLAY XAUTHORITY" to the sudoers(5) file using visudo(8). You can check what environment variables sudo preserves by running:

sudo sudo -V

(Yes, you type sudo twice). I recommend putting the line not in the default sudoers file (/etc/sudoers), but in a local file that won't get overwritten when you upgrade your system. You can do that like so:

sudo visudo -f /etc/sudoers.d/local 

But wait, what if none of the above works?

I think this is a fairly thorough answer, but if you're still having trouble, there's one other thing I'd suggest. You can use xhost(1) to grant access to a specific user on the local host (your machine) like so,

xhost si:localuser:root

In this case, we're specifying root as the username, since that's the account that sudo runs programs as.


[*]: Q: I've only got one screen, so why does an X display need an "address"? A: It's because X can work not only on your machine, but over the internet. With X, it's easy to run programs on your machine that show up on other internet hosts and programs on other hosts that appear on your screen (assuming you give them permission).


XDG_RUNTIME_DIR is an environment variable set in your X Windows context, so that programs can find things. You (neo) have set up the graphics context.

By trying to run evince as root, you have entered the condition where a user (root) is trying to access another user's (neo) display. This is regarded as a Bad Thing.

If you decide you MUST run a graphical editor as root, read man gksudo and make use of gksudo.