[gelöst] lokal angemeldeten X Benutzer finden

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

[gelöst] lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 03.10.2014 21:27:00

Hallo schon wieder,

sehr oft komme ich in die Verlegenheit in einem Skript herausfinden zu wollen, welcher Benutzer gerade lokal in X am System etwas macht. In diesem Fall ist es eine udev-Regel für Patsche, die mit xrandr die Bildschirmanschlüsse automatisch umschalten soll, aber vor dem gleichen Problem stehe ich, wenn ich mit notify-send von einem als root ausgeführten Skript benachrichtigt werden will.

Also das beste, was mir bisher eingefallen ist

Code: Alles auswählen

w -s | grep -v "tty/&pts/" | grep ":0 " | awk '{print $1}'
aber ich habe so eine Ahnung, dass das nicht in allen Situationen problemlos funktionieren wird.

Ich dachte auch schon mit

Code: Alles auswählen

ck-list-sessions
ein geeignetes Werkzeug gefunden zu haben, aber erstens verschweigt mir das aus irgendeinem Grund, welche Sitzung grafisch ist und außerdem wird consolekit ja sowieso gerade durch systemd ersetzt, ist also wohl nicht sehr zukunftsträchtig.

Für andere Vorschläge und Ideen wäre ich dankbar
lg smutbert
Zuletzt geändert von smutbert am 10.10.2014 21:04:27, insgesamt 1-mal geändert.

Fossler69
Beiträge: 57
Registriert: 08.08.2014 17:48:57
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Nomade

Re: lokal angemeldeten X Benutzer finden

Beitrag von Fossler69 » 04.10.2014 01:00:46

'who' tut es nicht?
smutbert@home:~$ who
smutbert tty7 2014-10-03 19:02 (:0)
smutbert pts/0 2014-10-04 01:02 (:0)
smutbert@home:~$

Benutzeravatar
The Hit-Man
Beiträge: 2170
Registriert: 21.11.2004 17:01:56
Wohnort: Menden ( Sauerland )
Kontaktdaten:

Re: lokal angemeldeten X Benutzer finden

Beitrag von The Hit-Man » 04.10.2014 01:17:22

so weit ich weiß, liegen die X-sessions im /tmp verzeichnis ...

/tmp/.X11-unix

alle angemeldeten X user die da drunter stehen, kannste dann einfach mit deinem script ( notify ) anschreiben.
Wer HTML postet oder gepostetes HTML quotet oder sich gepostetes oder
gequotetes HTML beschafft, um es in Verkehr zu bringen, wird geplonkt.

damals windows, früher ubuntu, danach debian, heute arch-linux ;)

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 04.10.2014 10:35:13

who und w, das ich verwende, haben ja sehr ähnliche Ausgaben. Mit fehlt der Weg herauszufinden, welche Sitzung gerade "aktiv" ist. Es könnte ja je eine x-session auf VT7 und VT8 laufen, da würde ich zusätzlich gerne noch wissen welches VT gerade dargestellt wird.

@The Hit-Man
Das bringt mich glaube ich nicht weiter, oder?

Code: Alles auswählen

$ ls -al /tmp/.X11-unix/
total 0
drwxrwxrwt 2 root root  60 Oct  4 09:02 .
drwxrwxrwt 9 root root 200 Oct  4 09:05 ..
srwxrwxrwx 1 root root   0 Oct  4 09:02 X0

Benutzeravatar
The Hit-Man
Beiträge: 2170
Registriert: 21.11.2004 17:01:56
Wohnort: Menden ( Sauerland )
Kontaktdaten:

Re: lokal angemeldeten X Benutzer finden

Beitrag von The Hit-Man » 04.10.2014 10:38:03

srwxrwxrwx 1 root root 0 Oct 4 09:02 X0
das bist du. mehr sind da nicht ... mach nen neuen X auf und du wirst ihn da finden.
Wer HTML postet oder gepostetes HTML quotet oder sich gepostetes oder
gequotetes HTML beschafft, um es in Verkehr zu bringen, wird geplonkt.

damals windows, früher ubuntu, danach debian, heute arch-linux ;)

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 04.10.2014 10:53:17

Ach so, das heißt er zeigt er root an, weil der Displaymanager (lightdm) X als root gestartet hat, obwohl ich als smutbert angemeldet bin. Das hilft mir zwar nicht direkt, aber immerhin weiß ich jetzt schon einmal, dass nur ein per displaymanager gestartete X als TTY die Display-Nummer in der who-Ausgabe hat. Hier habe ich mich als smutbert per lightdm angemeldet und auf tty3 mit startx als root ein zusätzliches X gestartet:

Code: Alles auswählen

$ who
smutbert  :0           2014-10-04 09:02 (:0)
root      tty3         2014-10-04 10:41
$ ls -l /tmp/.X11-unix/
insgesamt 0
srwxrwxrwx 1 root root 0 Okt  4 09:02 X0
srwxrwxrwx 1 root root 0 Okt  4 10:41 X1
und fgconsole liefert mit als root das aktive VT

Code: Alles auswählen

# fgconsole 
7
jetzt fehlt mir eigentlich nur noch eine Möglichkeit Zeilen wie oben die erste in der Ausgabe von who einem bestimmten VT zuordnen zu können. :0 wird zwar so gut wie immer auf VT7 sein, aber etwas allgemein gültiges wäre schön…

Danke

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: AW: lokal angemeldeten X Benutzer finden

Beitrag von scientific » 04.10.2014 18:35:57

Für notify als root:
Da muss man mit dbus arbeiten.
Wenn ich wieder am Rechner bin, schick ich dir ein Skript dazu.

Hab das bei cron- und incron-jobs im Einsatz, damit ich als eingeloggter XUsers benachrichtigt werde.

Lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: AW: lokal angemeldeten X Benutzer finden

Beitrag von scientific » 04.10.2014 18:36:59

Ach ja... Und "pinky" ist auch ein heißer Tipp. Schick dir da auch was.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 04.10.2014 22:57:18

Danke, die Geschichte mit dbus habe ich, glaube ich, im Griff. Mir geht es wirklich nur darum einen Benutzernamen herauszufinden (wenn ich mit mehreren auch zufrieden wäre, wäre es leichter).

Ich glaube ich habe das gewünschte mit loginctl gefunden. Das einzige was mich noch stört ist, dass ich zuerst mit

Code: Alles auswählen

loginctl
die Liste der Sitzungen holen muss und sie dann mit

Code: Alles auswählen

loginctl show-session $SESSION
durchgehen muss, um herauszufinden welche Sitzung aktiv, nicht remote und und vom Typ x11 ist.

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: lokal angemeldeten X Benutzer finden

Beitrag von scientific » 05.10.2014 09:33:18

Dieses Skript hab ich selber (nach einer Anleitung) geschrieben. Es sucht alle X-Sessions, damit ein Cron-job von root die eingeloggten User per notify informieren kann, was es so zu informieren hat. Vielleicht kannst du ja etwas daraus brauchen.

Code: Alles auswählen

#!/bin/sh

# Dieses Skript stellt div. Funktionen für meine Skripte zur Verfügung.
# Dieses Skript wird in anderen Skripten gesourced

# sendet an alle graphisch angemeldeten User eine Nachricht an den notify-daemon

dbusnotifying () {

case $1 in
	-i) shift; export ICON="$1"; shift;;
esac

export message="$@";
who|awk '$NF ~ /:/{print $1}'|uniq|while read user
do
	pids=`pgrep -u $user`
	for pid in $pids; do
		# find DBUS session bus for this session
		grep -z DBUS_SESSION_BUS_ADDRESS \
	 	/proc/$pid/environ 2>/dev/null | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//'
		echo
	done|sort -u|uniq|sed -e '/^$/d'|while read DBUS_SESSION_BUS_ADDRESS
	do	# use it
		export DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS"
		[ -n $DBUS_SESSION_BUS_ADDRESS ] || continue
		if [ x"$UID" == "x" ] ;then UID=0; fi
		if [ `echo $UID` -gt 0 ];
		then
			/usr/bin/notify-send -t 2000 -i "$ICON" "`basename "/"$0|sed -e 's/^-//'`" "$message"
		else
#echo x$UID
			#su $user -c "notify-send -t 2000 -i "$ICON" '`basename "/"$0|sed -e 's/^-//'`' '$message' 2>/dev/null" 2>/dev/null
			sudo -u $user /usr/bin/notify-send -t 2000 -i $ICON "`basename "/"$0|sed -e 's/^-//'`" "$message"
		fi
		test $? -eq 0  && break
		#[ -z $DBUS_SESSION_BUS_ADDRESS ] || break
		unset DBUS_SESSION_BUS_ADDRESS
	done
done
}

Und dieses Skript sollte alle aktiven X11-Sessions suchen und den dort laufenden xscreensaver sperren. Tut aber noch nicht ganz was es soll... (hab ich glaub ich aus dem archlinux-Forum)

Code: Alles auswählen

#!/bin/sh

# Lock xscreensaver on resume from a suspend.

# getXuser gets the X user belonging to the display in $displaynum.
# If you want the foreground X user, use getXconsole!
getXuser() {
        user=`pinky -fw | awk '{ if ($2 == ":'$displaynum'" || $(NF) == ":'$displaynum'" ) { print $1; exit; } }'`
        if [ x"$user" = x"" ]; then
                startx=`pgrep -n startx`
                if [ x"$startx" != x"" ]; then
                        user=`ps -o user --no-headers $startx`
                fi
        fi
        if [ x"$user" != x"" ]; then
                userhome=`getent passwd $user | cut -d: -f6`
                export XAUTHORITY=$userhome/.Xauthority
        else
                export XAUTHORITY=""
        fi
        export XUSER=$user
}

if pidof xscreensaver > /dev/null; then
    for x in /tmp/.X11-unix/*; do
        displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
        getXuser;
        if [ x"$XAUTHORITY" != x"" ]; then
            export DISPLAY=":$displaynum"
echo "Command: "$1
            case "$1" in
                resume|thaw)
        echo resume
                    sudo -u $XUSER xscreensaver-command -unthrottle
                ;;
                suspend|hibernate)
        echo $suspend
                    sudo -u $XUSER xscreensaver-command -throttle
                    sudo -u $XUSER xscreensaver-command -lock
                ;;
            esac
        else
echo $XUSER
        fi
    done
fi
lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: lokal angemeldeten X Benutzer finden

Beitrag von scientific » 05.10.2014 11:08:09

Zum zweiten Script muss ich noch sagen...

Ich eröffne eine Zweite Instanz von lightdm mit

Code: Alles auswählen

dm-tool switch-to-greeter
und logge mich dort als anderer User ein.

pinky liefert mir dann

Code: Alles auswählen

root@debian :/etc/systemd/system # pinky -fw
scientific    *tty1     00:22  2014-10-05 09:53
scientific     pts/1    01:09  2014-10-05 09:53 :0
root      pts/3    00:02  2014-10-05 10:54 :1
das Spannende dabei...das ist ein xterm, wo ich als root eingeloggt bin. also liefert mir dieses Skript nicht wirklich die Xsession und sperrt diese per xscreensaver... Vielleicht werde ich doch einen anderen Ansatz wählen, um beim Suspend per systemd alle Laufenden X-Sessions zu sperren.
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: lokal angemeldeten X Benutzer finden

Beitrag von scientific » 05.10.2014 17:10:41

Hab jetzt mal herumgetestet... Die Frage ist in der Tat nicht einfach zu lösen... pfff...

who und w geben nur Terminals und Xterminals aus. Also ein X gestartet mit einem einfachen Windowmanager gestartet mit startx gibt ebensowenig Ergebnis mit who und w wie auch loginctl stumm bleibt.
Aber auch bei einem Start eines Windowmanagers ohne xterm über den Displaymanager lightdm schweigt sich who und w aus. Allerdings spuckt loginctl dann etwas aus.

Ich arbeite nämlich grad (angeregt durch deine Fragestellung) weiter an einer voll funktionsfähigen Lösung, alle X-Sesseions bei einem Suspend zu sperren...

Code: Alles auswählen

loginctl lock-session
macht nämlich weder bei einer Xfce noch bei einer Fvwm-Sitzung irgendetwas. xscreensaver reagiert darauf nicht. Und gnome-screensaver scheint auch nicht darauf zu hören. Und eine Gnome-Shell hab ich nicht installiert, um es dort testen zu können...

In erster Linie baue ich gerade an einer zuverlässigen Erkennung von allen laufenden X-Sessions, um sie dann mit einem angepassten Befehl sperren zu können.

Der Teil aus dem vorhin genannten Skript

Code: Alles auswählen

        if [ x"$user" = x"" ]; then
                startx=`pgrep -n startx`
                if [ x"$startx" != x"" ]; then
                        user=`ps -o user --no-headers $startx`
                fi
        fi
liefert mir zwar die User, welche mit startx eine X-Session gestartet haben, jedoch krieg ich damit wieder das Display nicht raus. Und loginctl schweigt sich eines dabei... :-/

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 05.10.2014 17:26:30

ohne es ausprobiert zu haben, loginctl lock-session funktioniert vielleicht nur, wenn der Lockscreen in einem Displaymanager eingebaut ist, der systemd-login nutzt also gdm3 (mit gnome?) oder Debianlightdm mit Debianlight-locker (letzteres ließe sich recht leicht in xfce integrieren)?

Danke
Deine Skripte, vor allem das getXuser(), haben mich auf die Funktionen in der Datei /usr/share/acpi-support/power-funcs aus Debianacpi-support-base gebracht. Dort scheinen sie nämlich herzukommen. Tatsächlich funktionieren bei mir aber weder getXconsole noch getXuser. Sie laufen zwar und der exit-Status ist 0, aber es wird keine der angegebenen Variablen ($XAUTHORITY, $DISPLAY, $XUSER) gesetzt.

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: lokal angemeldeten X Benutzer finden

Beitrag von scientific » 05.10.2014 19:06:31

Freut mich, dir auch mal einen guten Hinweis geben haben zu können. :)

Ich hab übrigens noch weiterrecherchiert und getestet.

Für xscreensaver ist xss-lock notwendig, damit dieser auf logind lock-session hört. Das ist aber weder in wheezy noch in dessen backports. Hab mir mal die Quellen aus Testing runtergeladen und das Paket gebaut und installiert. Ganz bugfrei dürfte es noch nicht sein, weil es manchmal mit hoher Last hängenbleibt...

Ich hab das Skript zum allgemeinen sperren von allen xscreensavern überarbeitet:

Code: Alles auswählen

#!/bin/sh 
 
# Lock xscreensaver on resume from a suspend. 
 
# getXuser gets the X user belonging to the display in $displaynum. 
# If you want the foreground X user, use getXconsole! 
getXuser() { 
        user="$1" 
        session=$2 
        if [ x"$user" != x"" ]; then 
                userhome=`getent passwd $user | cut -d: -f6` 
                export XAUTHORITY=$userhome/.Xauthority 
        else 
                export XAUTHORITY="" 
        fi 
 
        export displays=`loginctl show-session $session|awk -F "=" '$1 == "Display" {print $2}'` 
        ## Suche nach X-Sessions mit startx für diesen User noch einbauen! 
#               startx=`pgrep -n startx` 
#                if [ x"$startx" != x"" ]; then 
#                        user=`ps -o user --no-headers $startx` 
#                fi 
        export XUSER=$user 
} 
 
if pidof xscreensaver > /dev/null; then 
    loginctl list-sessions|awk '$1 ~ /^[0-9]/ {print $1,$3}'|while read session user; do 
    #loginctl list-users|awk '$1 ~ /[0-9]*/ {print $2}'|while read user;do 
        getXuser $user $session; 
        if [ x"$XAUTHORITY" != x"" ]; then 
            for display in $displays; do 
               export DISPLAY=$display 
               case "$1" in 
                   resume|thaw) 
                       sudo -u $XUSER xscreensaver-command -unthrottle 
                   ;; 
                   suspend|hibernate) 
                       #loginctl lock-session $session 
                       sudo -u $XUSER xscreensaver-command -throttle 
                       sudo -u $XUSER xscreensaver-command -lock 
                   ;; 
               esac 
           done 
        fi 
    done 
fi 
loginctl kommt aber auch schön durcheinander... ich habe testweise eine X-Session über lightdm für user1 gestartet, eine für user2 und einmal ist user1 auf tty1 eingeloggt und ich habe eine zweie X-Session für user 1 über startx von tty1 aus gestartet.
Es ist also
:0 user1
:1 user2
:2 user1

ck-list-session scheint aber das einzige Werkzeug zu sein, dass schön Auskunft über alle X11-Sessions gibt. Kann es sein, dass systemd/logind schon in Hinblick auf Wayland "optimiert" ist?

Danke übrigens auf den Hinweis mit dem acpi-Skript. ev. kann man das ja sourcen in einem eigenen Skript. Aber zuverlässig arbeitet es bei mir auch (noch) nicht...

lg scientific
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: lokal angemeldeten X Benutzer finden

Beitrag von Cae » 05.10.2014 19:36:59

Hat denn jeder X-Benutzer eine Xauthority-Datei? Falls ja, waere

Code: Alles auswählen

# getent passwd | cut -d: -f1,6 | tr : ' ' | while read user home; do [ -f "$home/.Xauthority" ] && echo "$user"; done
user
# 
eindeutig. Per xhost zugelassene Benutzer erhalten z.B. keine ~/.Xauthority, sind aber auch nicht "lokal angemeldet".

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 05.10.2014 20:29:47

Danke, der Thread hat mir jetzt schon unglaublich viele weitere Ideen gebracht.

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: [gelöst] lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 10.10.2014 21:07:59

So sieht jetzt meine Lösung mit loginctl aus und hier viewtopic.php?f=37&t=151777 habe ich sie gleich ausprobiert :mrgreen:

Code: Alles auswählen

#!/bin/sh
for i in $(loginctl --no-legend list-sessions | awk '{print $1}')
do
        eval $(loginctl show-session ${i} | grep -e "Name=" -e "Remote=" -e "Type=" -e "Active=" -e "Display=")
        if [ ${Active} = "yes" ] && [ ${Type} = "x11" ] && [ ${Remote} = "no" ]
        then
                NameHome=$(getent passwd ${Name} | cut -d: -f6)
                export XAUTHORITY=${NameHome}/.Xauthority
                export DISPLAY=${Display}
                su ${Name} -c "notify-send 'hello world!'"
        fi
done
Danke noch einmal

scientific
Beiträge: 3020
Registriert: 03.11.2009 13:45:23
Lizenz eigener Beiträge: Artistic Lizenz
Kontaktdaten:

Re: AW: [gelöst] lokal angemeldeten X Benutzer finden

Beitrag von scientific » 11.10.2014 01:43:23

Erkennt deine Lösung auch Sessions, die mit startx gestartet sind?
dann putze ich hier mal nur...

Eine Auswahl meiner Skripte und systemd-units.
https://github.com/xundeenergie

auch als Debian-Repo für Testing einbindbar:
deb http://debian.xundeenergie.at/xundeenergie testing main

Benutzeravatar
smutbert
Moderator
Beiträge: 8320
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: [gelöst] lokal angemeldeten X Benutzer finden

Beitrag von smutbert » 11.10.2014 17:20:44

Nein, so wie sie hier steht, nicht. Als "Type" ist bei direkt von VTs aus gestarteten Xorg bei meinen Tests immer "tty" und nicht "x11" herausgekommen. Man könnte einfach die Abfrage nach dem "Type" weglassen, dann würde schlimmstenfalls ein fruchtloses notify-send an eine Anmeldung im Textmodus abgesetzt, aber dasselbe gilt ja auch für X-Sessions ohne notification-daemon.

Im anderen Thread hat Cae die Verwendung von eval (noch dazu als root) für die Ausgabe von loginctl angekreidet und das ist wphl auch wirklich nicht besonders schön, aber ich habe noch keine bessere Lösung gefunden, die mir gefällt.

Antworten