Erkennen einer X-Sitzung in einem Bash-Skript (.bashrc usw.)

16

Vor kurzem habe ich xset b offmeine .bashrc. Jetzt ärgere ich mich über den Fehler, der auftaucht, wenn ich mich über tty oder über ssh anmelde, also außerhalb der X-Sitzung.

Das erste, was mir in den Sinn kam, war [[ -z "$SOME_VAR" ]] && xset b off(nun, es stellt sich heraus, dass das Setzen einer Testvariablen im Vergleich zum Leeren eine andere Frage ist). Aber welche SOME_VAR ist die richtige?

Also habe ich die Ausgabe von tty setund urxvt differenziert, um setzu sehen, welche Variablen in X gesetzt sind und in tty fehlen. Wie erwartet gab es ziemlich viele Unterschiede (nur die auflisten, die mir relevant erschienen):

  • DESKTOP_SESSION
  • DISPLAY
  • GDMSESSION
  • SESSION_MANAGER
  • WINDOWID
  • WINDOWPATH
  • XAUTHORITY
  • XDG_SESSION_COOKIE
  • XDG_CONFIG_DIRS
  • XDG_DATA_DIRS
  • XDG_MENU_PREFIX

Welches ist das Richtigste und Universellste, um festzustellen, ob ich in einer X-Sitzung bin oder nicht? Etwas, das in möglichst vielen Distributionen, Plattformen und Desktop-Umgebungen funktioniert?

Oder gibt es einen besseren Weg als Umgebungsvariablen zu testen?

Alois Mahdal
quelle

Antworten:

8

Eine einfache und effektive Möglichkeit, um zu testen, ob Ihr Anzeigeserver verfügbar und gültig ist, besteht darin, ihn mit zu testen xhost. Sie können sich nicht immer darauf verlassen, nach einem Wert in der DISPLAYVariablen zu suchen, da dieser möglicherweise mit einem ungültigen Wert festgelegt wurde.

if xhost >& /dev/null ; then echo "Display exists"
else echo "Display invalid" ; fi

Der Grund dafür ist, dass ich in meinem Benutzer mehrere Skripts ausführe crontab, die auf der Anzeige ausgeführt werden, wenn sie vorhanden ist, aber anders arbeiten, wenn sie nicht vorhanden sind. Oben in meiner Liste habe crontabich die DISPLAYVariable auf gesetzt :0, obwohl sie noch nicht existiert. Skripte crontab, die mit @rebootbeginnen, werden unabhängig davon gestartet, ob Sie eine Anzeige haben oder nicht. Auf diese Weise können Sie dynamisch erkennen, wann Ihre Anzeige im selben Skript ein- und ausgeht.

HINWEIS: Das >&funktioniert nur in bash> = 4. Ansonsten verwenden> /dev/null 2>&1

cmevoli
quelle
Schön, getestet auch mit ssh -X; funktioniert gut!
Alois Mahdal
13

Ich denke, das Überprüfen DISPLAYwäre der beste Ansatz.

  • Es behandelt entfernte Logins (zB ssh -X).
  • Es ist auf den meisten - wenn nicht allen - Plattformen verfügbar.
  • Es ist unabhängig von Window Manager / DE.
Renan
quelle
2
Ich würde auch versuchen DISPLAY, die Fehlermeldung im Allgemeinen zu unterdrücken. Gib /dev/nullvon Zeit zu Zeit etwas Liebe.
Frostschutz
3
@frostschutz Nein, ich versuche nur relevante Teile des Skripts auszuführen. Das Unterdrücken von Fehlermeldungen führt zu keinem Schritt in diese Richtung. Tatsächlich kann dies zu ernsthaften Verwirrungen bei der Fehlerbehebung bei anderen Dingen führen, die möglicherweise beschädigt werden können.
Alois Mahdal
1
Ich habe diesen Ansatz kurz nach der Antwort verwendet, und er funktionierte sshbis jetzt perfekt mit einfachen s, als ich anfing, ssh -XVim über ssh zu verwenden, damit der im visuellen Modus ausgewählte Inhalt in die lokale X-Zwischenablage gelangt, für die Sie brauchen keinen xserver auf der Serverseite. DISPLAY wird also so eingestellt, dass die Weiterleitung einfach aktiviert wird, auch wenn xserver und xset nicht vorhanden sind.
Alois Mahdal
Das wäre dann:if [[ $DISPLAY ]]; then … fi
Serge Stroobandt
1
Ihre DISPLAYVariable kann auf eine Anzeige verweisen, auf der tatsächlich kein X-Server ausgeführt wird (z. B. wenn sie in einem Skript fest codiert ist oder der X-Server heruntergefahren wurde, nachdem die Variable festgelegt wurde).
16.
6

Normalerweise benutze ich die TERMVariable, um in meinen Skripten auf X zu testen.

TERMwird normalerweise linuxauf TTY und xtermauf X gesetzt.
Ich verwende hier das Wort "normalerweise", da Anwendungen wie GNU Screen und TMux mit der TERMVariablen zu verwechseln scheinen .

verdammt
quelle
Versuchen echo $TERMSie, die Richtungsangaben an Ihrer Maschine auf verschiedenen Konsolen zu ermitteln. Ich benutze [ $TERM == "linux" ] && echo do some stuffauf Ubuntu
rubo77
3

Dies sollte einwandfrei funktionieren:

[ ! -t 0 ] && xset b off                                  

http://tldp.org/LDP/abs/html/fto.html

-t

    file (descriptor) is associated with a terminal device

    This test option may be used to check whether the stdin [ -t 0 ] 
    or stdout [ -t 1 ] in a given script is a terminal.

Wenn dies zu false ( [ ! -t 0 ]) ausgewertet wird, befinden wir uns in einer GUI-Umgebung.

terdon
quelle
Damit erhalte ich sowohl in X als auch in der Konsole das gleiche Ergebnis, [ -t 0 ]und zwar und [ -t 1 ]sind beide wahr.
Emanuel Berg
Seltsamerweise funktioniert es bei mir, wenn ich in einen Remote-Host sshinge.
Terdon
[ -t 0 ]funktioniert
einwandfrei
0

Es gibt viele Möglichkeiten, wie Sie das tun können.

Versuchen Sie es in der Bash

function xruns {
    if [[ `pstree -As $$ | grep xinit | wc -l` == 1 ]]; then
        echo "You are in X."
    else
        echo "You are not in X."
    fi
}

Oder versuchen Sie es in zsh

#!/usr/bin/zsh

CURRENT_VT=`tty`

if [[ ${CURRENT_VT[6]} == "p" ]];        # or `${CURRENT_VT:5:1}` in bash
then
   # X stuff
else 
   # non-X stuff      
fi
Emanuel Berg
quelle
Punkt genommen, aber testen Sie Ihren Code vor dem Posten? Der erste hat einen Syntaxfehler und erkennt nicht, ob wir uns in einer X-Sitzung befinden, so dass dies der Fall ist, wenn echo 1X ausgeführt wird und Sie sich über tty1-6 oder ssh anmelden. Der andere macht immer "non-X stuff" - ich denke das ${CURRENT_VT[6]}bedeutet eher die 6. Zeile als das 6. Zeichen.
Alois Mahdal
@AloisMahdal: Aha, meine Sachen funktionieren nicht in bash (ich benutze zsh). Daran habe ich nicht gedacht. Nun, Sie könnten es in zsh (Typ zsh) versuchen und möglicherweise einige Änderungen vornehmen, wenn Sie möchten, damit es in bash funktioniert.
Emanuel Berg
@AloisMahdal: OK, ich habe es geändert. Was die "Anmeldung über tty1-6" betrifft, so mache ich das, und dann verwende ich die zweite Lösung (oben) und setze eine Variable. Schauen Sie sich das an .zshrc und suchen Sie nach export VT. Ich verwende die Variable, um das Linux-VT / console / tty zu speichern, in dem ich mich befinde (für die zsh-Eingabeaufforderung), aber in X setze ich es einfach auf "X" (obwohl kein VT). Aber das sind Details, Sie können es nach dem gleichen Prinzip herausfinden, wie Sie es möchten.
Emanuel Berg
Ich habe dem zweiten Beispiel eine Bash-Version der Bedingung hinzugefügt. Ich denke jedoch, dass der erste immer noch falsch ist. Vielleicht würde es helfen, wenn ps nur Vorfahren druckt . Ich bin mir jedoch nicht sicher, ob es möglich ist.
Alois Mahdal
@AloisMahdal: Schau dir die Bearbeitung an. Das macht es für mich, einschließlich der tty Sachen.
Emanuel Berg
0

if [[ $DISPLAY ]]

Auf dem gleichen Computer $DISPLAYwird beispielsweise 0:0in einem Terminal-Emulator nichts zurückgegeben, aber in einem echten Terminal. Dies kann leicht mit CtrlAltF1versus getestet werden CtrlAltF7.

Eine bashBedingung basierend auf $DISPLAYwürde wie folgt aussehen:

if [[ $DISPLAY ]]; then 
  
fi
Serge Stroobandt
quelle