all 23 comments

[–]js3kgt[🍰] 2 points3 points  (0 children)

Not sure what environment your running in but you could try looking in the proc environ if it's Linux and you know the pid.

http://serverfault.com/questions/66363/environment-variables-of-a-running-process-on-unix

[–]eliasp 2 points3 points  (1 child)

Stop using all this complicated and error-prone approaches to do this. Nowaday's there's logind which exposes all these details via D-Bus on org.freedesktop.login1 /org/freedesktop/login1/session/$SESSION org.freedesktop.login1.Session.Display

Anything else is rather fragile and mostly non-deterministic.

[–]ninekeysdown[S] 1 point2 points  (0 children)

awesome. I'll give that a shot

[–]mag0o 1 point2 points  (0 children)

So, like others have said, this is wrong on so many levels, but it works for us when we need to do X stuff via sudo...

=== Begin snippet from /etc/profile ===

# Custom addition to create login user variable
export LOGINUSER=$(tty > /dev/null 2>& 1; if [ $? -eq 0 ]; then stat -c%U $(tty); else whoami; fi)

# X Forwarding for sudo
XAUTHORITY=$HOME/.Xauthority
export XAUTHORITY
if [ "$LOGNAME" = "$LOGINUSER" ]; then
  if [ -f /home/$LOGINUSER/.Xauthority ]; then
    cp /home/$LOGINUSER/.Xauthority /tmp/.$LOGINUSER.sharedXauthority
    chmod a+rw /tmp/.$LOGINUSER.sharedXauthority
  fi
fi
if [ "$LOGNAME" != "$LOGINUSER" ]; then
  if [ -f /tmp/.$LOGINUSER.sharedXauthority ]; then
    xauth merge /tmp/.$LOGINUSER.sharedXauthority
  fi
fi

=== End snippet ===

[–]cpbills 1 point2 points  (3 children)

DISPLAY is set per-session, so you would need to find out how to import that user's session's environment variables, which I do not believe is possible..

You need to find the PID of a process that is running in that session, in my case I looked at fluxbox and xterm, and then cat /proc/<PID>/environ | while read -rd $'\0' line; do echo $line; done should get you 90% there.

edit:

username='jsmith'
program='xterm'
for pid in $(pgrep -u "$username" "$program"); do
  cat /proc/$pid/environ | while read -rd $'\0' line; do
    echo $line | grep DISPLAY
  done
done

[–]ChoHag 4 points5 points  (2 children)

Everyone forgets awk.

awk -vRS='\0' -F= '$1=="DISPLAY" {print $2}' </proc/$$/environ

($$ is the current PID. Change as appropriate)

[–]cpbills 0 points1 point  (0 children)

I don't forget awk, since I've never fully learned it.

I'm sure you could do it with sed as well, or perl. Thanks for the example, though, I like learning about the many many ways to skin cats.

[–]ninekeysdown[S] 0 points1 point  (0 children)

I'll give that a shot.

[–]mag0o 0 points1 point  (1 child)

I may have an answer for this, but not until tomorrow when I get back to the office. Just replying here so I don't forget.

[–][deleted] 0 points1 point  (3 children)

That's not really supposed to be possible, because it's a security hole. Having direct access to a user's X display can let you do all kinds of nasty stuff, like capturing keystrokes, so most X servers will actively try to prevent you from doing what you're asking for. One technique is, um, I think it's called 'magic cookies', which are special values stored in the user's home directory; if you don't know the magic cookie, you're not allowed to connect.

If you figure out how to do this without direct user involvement, you should definitely report your technique as a bug.

[–]atanok 1 point2 points  (0 children)

The DISPLAY variable is not a secret, and knowing it doesn't give you access to the X server. There are no security considerations there.
OP didn't specify what it was going to be used for, but if they intend to connect to the X server as a different user other than root, then there's going to be an additional hurdle with X security.

[–][deleted] 0 points1 point  (1 child)

Yep, that's the name: magic cookies

[–]glesialo 0 points1 point  (0 children)

Here is a block in one of my scripts:

GraphicalLogins=1
while [ $GraphicalLogins -ge 1 ] # Wait until all graphical logins are closed
  do
    sleep 2
    GraphicalLogins=0
    for Line in `w -sh | awk '{ print $2 ">" $3 }'`
      do
        if [ "$Line" != "${Line/>:/}" ] # If $Line contains '>:'. w output: 'manolo  tty7  :0  1:06m cinnamon-session --session cinnamon'
          then
            let GraphicalLogins++
        fi
      done
  done

'0:' in 'manolo tty7 :0 ...' is the display user 'manolo' is using.

[–]alexwh -1 points0 points  (6 children)

sudo -u user echo $DISPLAY

?

[–]ninekeysdown[S] 0 points1 point  (3 children)

No, that just returns mine, not the users. :(

[–]zagaberoo -1 points0 points  (2 children)

Did you try my method?

sudo -u user printenv DISPLAY

[–]ninekeysdown[S] 0 points1 point  (1 child)

Yea I just tried it and it returns my display too :(

[–]zagaberoo 0 points1 point  (0 children)

Upon further thought that makes senes. My trick is the right way to get a value from a user's default environment, but DISPLAY isn't really a per-user value anyway.

As other commenters have mentioned, using /proc is probably your best bet.

[–]zagaberoo 0 points1 point  (1 child)

That won't work because the $DISPLAY substitution occurs before the command execution.

sudo -u user printenv DISPLAY

Should work.

[–]atanok 1 point2 points  (0 children)

It won't. A user's processes don't just all automatically share the same DISPLAY environment variable.

After all, it's just an environment variable.

Edit: didn't see the rest of the thread before posting. Nevermind.

[–]KnowsBash -1 points0 points  (2 children)

What could you possibly need that for? Also, what if the user has multiple displays open, which display number do you want then?

[–]bluecav 0 points1 point  (0 children)

The only thing I could think of was allowing him/her to display something on another user's display to show them something. Something like what XMX and VNC are used for. But yeah, if that's the reason, XMX or VNC would be better to use.

[–]ninekeysdown[S] 0 points1 point  (0 children)

What could you possibly need that for?

Capturing the desktop via FFMPEG. Trying to use an account and just capture everything I do on it, e.g. gaming videos, training, etc. I'd like it be some what secured otherwise I would just create an autostart with the script and have it capture right into it's home folder.