How to find out the current (active) XServer DISPLAY number?
Solution 1
You may try to use loginctl list-sessions
to get the list of sessions, and then use loginctl show-session -p Display -p Active <session ID>
on each of these to get the X11 display number associated with the currently active session.
Something like this (in bash):
TARGET_DISPLAY=()
while read id uid user seat; do
while IFS='=' read property value; do
case "$property" in
Active)
if [[ "$value" != "yes" ]]; then continue; fi
;;
Display)
if [[ "$value" ]]; then
TARGET_DISPLAY+=( "$value" )
fi
# else the session isn't graphical
;;
esac
done < <(loginctl show-session -p Display -p Active "$id")
done < <(loginctl list-sessions --no-legend)
Here the $TARGET_DISPLAY
is an array, because hypothetically there may be more than one active session (on a multi-seat system). If this is not possible in your configuration, you may make it a simple variable and add a break 2
statement after the assignment to exit both loops.
HOWEVER...
...this does not anymore work with GDM, because in this case the X server is started inside the session (with user privileges) and /usr/bin/gdm-x-session
does not communicate this information back to logind
(due to lack of an API for that).
In other cases (when the X server is started by the DM before the session is created) this will most probably work. I'm not aware of any other methods, sorry.
Solution 2
Well, as current I mean active Display of a XOrg Server. Remember that we can have more than one XOrg Server running and they can be multi-head, what make the things harder to manipulate.
The other important note is that the DISPLAY variable in some cases cannot be accessed (eg. systemd).
After some discussion in commandlinefu, I got this result:
for p in $(pgrep -t $(cat /sys/class/tty/tty0/active));
do
d=$(awk -v RS='\0' -F= '$1=="DISPLAY" {print $2}' /proc/$p/environ 2>/dev/null);
[[ -n $d ]] && break;
done;
echo $d
This snippet iterates over a list of all processes (actually their IDs) where the controlling terminal is set and matches the terminal of this process. It checks each process' environment for the DISPLAY
variable and is satisfied as soon as it finds one. Having found a DISPLAY
variable it stops iterating the list and echo
s the result.
That will print the active display which run the script.
Solution 3
Here's an example with two servers running on the same host. I used startx
to launch both of them, as you can see from the output of pstree -pl
below. The first child process with $DISPLAY
set is .xinitrc
:
|-login(698)---zsh(1077)---startx(1359)---xinit(1381)-+-.xinitrc(1386)...
This is the command; if you have a different setup, you could change .xinitrc
to something else here:
$ pgrep .xinitrc | while read i; do \
d=$(cat /proc/$i/environ | tr '\0' '\n' | grep DISPLAY); \
echo -n $d" "; eval $d xprintidle; \
done | sort -n -k 2
DISPLAY=:1 93
DISPLAY=:0 603301
The numbers show the idle time of each display, in milliseconds. The top line shows the most recently active (least idle) display.
For what it's worth, none of the other answers worked for me.
Solution 4
This is my solution based on other answers:
#!/bin/bash
DISPLAY=""
# Guess the active DISPLAY
while read session; do
# Explode to needed variables
set -- $session; tty=$2; display=$3
# If there is an X session in thet TTY
if [ "$display" != "-" ]; then
# 1st non root display is used if TTY is not matched with the active
[ "$DISPLAY" == "" ] && DISPLAY="$display"
# If it is the active TTY we can stop, this is the active X!
[ "$tty" == "$(cat /sys/class/tty/tty0/active)" ] && DISPLAY="$display";
fi
done <<< "$(w -hs)"
echo "$DISPLAY"
This checks all login sessions which have X sessions as well. If the tty is also match we can be sure it is the active X session, else we use the 1st one.
This script can be extended to match current user as well if you want.
Solution 5
Next script lists user name and display number for logged in users when the corresponding terminal is active.
w -hs | \
awk -v tty="$(cat /sys/class/tty/tty0/active)" \
'$2 == tty && $3 != "-" {print $1 FS $3}'
Result:
myuser :0
Related videos on Youtube
Skillet
Updated on September 18, 2022Comments
-
Skillet over 1 year
I'm using Arch Linux and things are not so easy when you try to discover the current Xorg DISPLAY (not through the env variable).
Here is a working example:
$ cat /sys/class/tty/tty0/active tty2 who | awk -v term="tty2" '/\(:/ $0 ~ term { gsub(/\(|\)/, "", $0); print $5 }' :0
That works in some cases, in others not:
$ cat /sys/class/tty/tty0/active tty3 who | awk -v term="`cat /sys/class/tty/tty0/active`" '/\(:/ $0 ~ term { gsub(/\(|\)/, "", $0); print $5 }' NOTHING
Cause:
$ who uzumaki tty2 2015-05-16 10:50 (:0) guest pts/2 2015-05-16 11:47 (:1) uzumaki tty4 2015-05-16 11:07
The guest user (tty3) had his session lauched using pts (pseudo terminal).
I'm using gdm and it launches xorg servers without a specific command (not clarifying the display number).
$ ps au | grep -e Xorg -e vt uzumaki 788 1.4 0.9 740464 150672 tty2 Sl+ 10:50 5:38 /usr/lib/xorg-server/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -verbose 3 guest 1062 0.0 0.1 465748 32344 tty3 Sl+ 10:51 0:19 /usr/lib/xorg-server/Xorg vt3 -displayfd 3 -auth /run/user/1002/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -verbose 3
So the million question is: How to find out the current (in use) XServer DISPLAY number? Current because, as above, we can have multiples servers (multiple users).
-
Bananguin almost 9 yearsWhy are you trying to find out the so called "current" XDISPLAY? What do you mean by "current"? Apparently you have at least two XServer running. Which is current and why?
-
-
Skillet almost 9 yearsHi @intelfx, here it didn't work:
loginctl list-sessions
returns c1, c2 and c3 as SESSIONS. Sologinctl show-session -p Display c1
orc2
or evenc3
returns always Display= -
Andrey Tigay almost 9 years@geyslan: Sorry, I've misremembered information which is returned by
loginctl list-sessions
-- there is no "ACTIVE" column... And, actually, situation turns out to be worse than I thought: starting with 3.16, GDM stopped passing the X11 display number tologind
due to a structural rework. Though this may work with other compliant DMs. -
Skillet almost 9 yearsNo problem @intelfx. Thank you for your help anyway.
-
Bananguin almost 9 yearsThis is a very greedy approach and needn't return the correct
DISPLAY
. You should evaluate all environments and assume the value ofDISPLAY
which you read most frequently. -
Bananguin almost 9 years@intelfx: very nice approach. In 1-2 major releases I may come to like this *d stuff. Just to throw in another idea: I once had to match XDisplays to usernames. I build a little something that looks at all incoming TCP connections to the various Xservers and does a majority vote on the users the connecting processes belong to. Works fairly well with modern DEs.
-
Skillet almost 9 years@bananguin Given some tty could more than one x server be running in it?
-
Bananguin almost 9 yearsyou are not looking at Xservers, only at environmental variables. We always need to be very careful about what we assume about environmental variables.
-
Skillet almost 9 yearsI see your caution. Do you have some code to suggest (bash)?
-
dirkt over 7 yearsThe question is ill-defined. I can easily have a dozen of "active" X-connections (some local, some remote), and I can have all of them in the same shell, on the same controlling tty. I can change
DISPLAY
at will, several times. You can look forDISPLAY
in the environment of processes you are interested in (you didn't say which ones), but that's all you can do.