43

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 ?

2
  • 2
    Tell us more about your operating system.
    – DK Bose
    Jan 17, 2017 at 10:28
  • 4
    Note that it's not a good idea to run evince or any other program that's commonly used to open untrusted files as root. Untrusted PDF files are maybe in top 3 for potential security attacks against your system. Sep 5, 2021 at 13:10

2 Answers 2

92

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).

4
  • 2
    Thank you for the elaborate answer. I'm sure there's at least something new in your answer for every user. (For me: how to grant access to X to a specific user, which is better than issuing xhost + to allow universal access.)
    – drumfire
    Nov 1, 2017 at 12:11
  • 1
    This is an exemplary answer! You are a hacker after my own heart. I've been using *nix since 1995 and I learned a lot from this. Thank you, friend. Mar 7, 2021 at 17:06
  • 1
    @MuhammadIllyas for pete's sake, EXCEPT THIS ANSWER!!! why is it that the very best answers are unaccepted??
    – Nate T
    Jun 13, 2021 at 2:58
  • This solution indeed resolve the OP's real question. However, it does not actually resolve "error: XDG_RUNTIME_DIR not set in the environment". For that, you need to investigate the PAM rules. Jan 28, 2022 at 7:41
5

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.

2
  • interesting comment. Do you happen to know then how i could to something like this ? journalctl -b -p err | wl-copy it reports Failed to connect to a Wayland server which makes sens, but sounds dumb from User POV.
    – mh-cbon
    May 28, 2019 at 12:28
  • 1
    A quick note. The variable has absolutely nothing to do with X Windows context. It is initialized regardless whether X is installed. It is set by systemd and defined in XDG Base Directory Specification here specifications.freedesktop.org/basedir-spec/…. Oct 18, 2022 at 23:30

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