1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
#! /bin/bash
#
# Determines the number of the virtual terminal that hosts the X-server.
# If there are multiple server running the one with biggest user-time is
# choosen. If there is no X running at all, nothing is printed.
# must be run as root.
# If no X-server or wrong usage it returns 1, else 0.
#
# Author: Christian Zoz <zoz@suse.de>
# Stefan Seyfried <seife@suse.de>
#
# Example usage:
# # switch to X
# chvt `wttyhx`
#
usage() {
echo "usage: $0 [-h] [-q] [-t]"
echo " -a: print all users that run a X server and the display numbers"
echo " -h: print a help message"
echo " -q: be quiet, dont print any output"
echo " -t: print a table of pids and vts of all running X server"
echo " -v: print tty, user, display and version of X"
echo " -3: also return 1 if XF86version is 3"
echo " -4: also return 1 if XF86version is 4"
echo "-a, -q, -t and -v are mutually exclusive"
exit 1
}
#getusername() {
# OLD_IFS="$IFS"
# IFS=:
# while read NAME PASS ID REST; do
# test "$1" = "$ID" && break
# done < /etc/passwd
# IFS="$OLD_IFS"
# echo "$NAME"
#}
getusername() {
local _IFS DUMMY
_IFS="$IFS"
IFS=:
read USERNAME DUMMY < <(getent passwd $1)
echo $USERNAME
IFS="${_IFS}"
}
getuserfromwho() {
while read NAME DISP REST; do
test "$1" = "$DISP" && break
done < <(who)
echo "${NAME:--}"
}
ACTION=tty
LEAVE=0
while [ $# -gt 0 ] ; do
case "$1" in
-a) ACTION=alluser ;;
-h)
echo " ${0##*/} determines the number of the virtual terminal that"
echo " hosts the X-server. If there are multiple server running that"
echo " with biggest user-time is choosen. If there is no X running at"
echo " all, nothing is printed."
echo " Additionally ${0##*/} can provide the user that owns the X"
echo " server and the major version of the server."
echo " If no X-server or wrong usage it returns 1, else 0"
usage
exit
;;
-q) ACTION="" ;;
-t) ACTION=table ;;
-v) ACTION=verbose ;;
-3) LEAVE=3 ;;
-4) LEAVE=4 ;;
*) usage ;;
esac
shift
done
declare -a XPIDS XTTYS BINARY VERSION UTIME
declare -a USER_WHO UID_WHO USER_W UID_W USER_REAL UID_REAL
declare -a DISP_PROC UID_PROC EUID_PROC SUID_PROC FSUID_PROC
declare -i n=0 m=0 uid_real uid
# Lets look for all running X server, their owner and their tty
pushd /proc &>/dev/null
for PID in `pidof X Xorg Xgl`; do
# At first search all XFree86 processes and get their versions and utime
BIN=`readlink $PID/exe`
case "$BIN" in
/usr/X11R6/bin/XFree86) VERSION[$n]=4 ;;
/usr/X11R6/bin/Xorg) VERSION[$n]=4 ;;
/usr/bin/Xorg) VERSION[$n]=4 ;;
/usr/bin/Xgl) VERSION[$n]=4 ;;
/usr/X11R6/bin/X) VERSION[$n]=3 ;;
*) continue ;;
esac
XPIDS[$n]=$PID
BINARY[$n]=${BIN##*/}
read pid comm state ppid pgrp session tty_nr tty_pgrp flags min_flt \
cmin_flt maj_flt cmaj_flt utime stime cutime cstime prio nice rest \
< $PID/stat
UTIME[$n]=$utime
# Then look for the tty that hosts X
for FD in $PID/fd/*; do
FDL=`readlink $FD`
test "${FDL%[0-9]*}" = "/dev/tty" && break
done
XTTYS[$n]=${FDL#/dev/tty}
# Get the display number from the commandline
DISP=`tr '\0' '\40' < $PID/cmdline | sed 's#^.*:\([0-9]\+\).*$#\1\n#'`
DISP_PROC[$n]=$DISP
# Finally get the user that owns the X server. We need different
# methods to get the real X user, because it depends on the version of
# the server and on how it was started. So we finally look for user
# id at several places and then take the user with the highest uid.
while read USER D R; do
test "$D" = "$DISP" && break
done < <(w -h | sed -n 's#^\([^ ]*\).* :\([0-9]\+\).*$#\1 \2#p')
USER_W[$n]=$USER; UID_W[$n]=`id -u $USER 2>/dev/null`
while read TAG U0 U1 U2 U3 R; do
if [ "$TAG" = "Uid:" ] ; then
UID_PROC[$n]=$U0
EUID_PROC[$n]=$U1
SUID_PROC[$n]=$U2
FSUID_PROC[$n]=$U3
fi
done < $PID/status
USER_WHO[$n]=`getuserfromwho ":$DISP"`
UID_WHO[$n]=`id -u ${USER_WHO[$n]} 2>/dev/null`
USER_REAL[$n]="root"; UID_REAL[$n]=0
for uid in ${UID_PROC[$n]} ${EUID_PROC[$n]} ${SUID_PROC[$n]} \
${FSUID_PROC[$n]} ${UID_WHO[$n]} ${UID_W[$n]}; do
test $uid -gt ${UID_REAL[$n]} && UID_REAL[$n]=$uid
done
USER_REAL[$n]=`getusername ${UID_REAL[$n]}`
: $((n++))
done
popd &>/dev/null
test $n -lt 1 && exit 1
# search the X server with biggest user-time
utime=0
while [ "$n" -ge 0 ] ; do
if [ "${UTIME[$n]:-0}" -gt "$utime" ] ; then
utime=${UTIME[$n]}
m=$n
fi
: $((n--))
done
case "$ACTION" in
table)
OLDIFS=$IFS
IFS=$'\t'
echo "pids: ${XPIDS[*]}"
echo "vt-proc: ${XTTYS[*]}"
echo "disp-proc: ${DISP_PROC[*]}"
# echo "uid-proc: ${UID_PROC[*]}"
# echo "euid-proc: ${EUID_PROC[*]}"
# echo "suid-proc: ${SUID_PROC[*]}"
# echo "fsuid-proc: ${FSUID_PROC[*]}"
# echo "user-who: ${USER_WHO[*]}"
# echo "user-w: ${USER_W[*]}"
echo "user: ${USER_REAL[*]}"
echo "utime: ${UTIME[*]}"
echo "binary: ${BINARY[*]}"
echo "version: ${VERSION[*]}"
IFS=$OLDIFS
;;
tty)
echo "${XTTYS[$m]}"
;;
verbose)
echo "${XTTYS[$m]} ${USER_REAL[$m]} :${DISP_PROC[$m]} ${VERSION[$m]}"
;;
alluser)
n=0
while [ -n "${USER_REAL[$n]}" ] ; do
echo -e "${USER_REAL[$n]}\t:${DISP_PROC[$n]}"
: $((n++))
done
;;
esac
if [ "$VERSION" -eq "$LEAVE" ] ; then
exit 1
fi
|