Détection de session X dans un script bash (.bashrc etc.)

16

Récemment, j'ai mis xset b offmon .bashrc. Maintenant, je suis ennuyé par l'erreur qui apparaît lorsque je me connecte via tty ou via ssh, c'est-à-dire en dehors de la session X.

La première chose qui m'est venue à l'esprit était [[ -z "$SOME_VAR" ]] && xset b off(eh bien, il s'avère que tester la variable définie par rapport à être vide est une question différente). Mais quel SOME_VAR est le bon?

J'ai donc différencié la setsortie de tty et la sortie d'urxvt setpour voir quelles variables sont définies dans X et manquantes dans tty. Comme prévu, il y a eu beaucoup de différences (en ne listant que celles qui me semblaient pertinentes):

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

Laquelle est la plus correcte et la plus universelle à tester pour détecter si je suis en session X ou non? Quelque chose qui fonctionnerait sur autant de distributions et de plateformes et d'environnements de bureau que possible?

Ou existe-t-il un meilleur moyen que de tester les variables d'environnement?

Alois Mahdal
la source

Réponses:

8

Un moyen simple et efficace de tester la disponibilité et la validité de votre serveur d'affichage consiste à le tester avec xhost. Vous ne pouvez pas toujours compter sur la vérification d'une valeur dans la DISPLAYvariable car elle peut être définie avec une valeur non valide.

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

La raison pour laquelle je fais cela est parce que j'exécute plusieurs scripts dans mon utilisateur crontabqui fonctionnent sur l'écran lorsqu'il existe, mais fonctionnent différemment dans le cas contraire. En haut de ma crontab, j'ai défini la DISPLAYvariable :0même si elle n'existe pas encore. Les scripts crontabqui commencent par @rebootcommenceront, que vous disposiez ou non d'un affichage. Cela vous permettra de détecter dynamiquement quand votre affichage va et vient dans le même script.

REMARQUE: le >&seul fonctionne dans bash> = 4. Sinon, utilisez> /dev/null 2>&1

cmevoli
la source
Nice, testé aussi avec ssh -X; fonctionne bien!
Alois Mahdal
13

Je pense que la vérification DISPLAYserait la meilleure approche.

  • Il gère les connexions à distance (par exemple ssh -X).
  • Il est disponible sur la plupart des plates-formes, sinon toutes.
  • Il est indépendant du gestionnaire de fenêtres / DE.
Renan
la source
2
J'irais également pour DISPLAY, ou supprimerais simplement le message d'erreur en général. Donnez de l' /dev/nullamour de temps en temps.
frostschutz
3
@frostschutz Non, j'essaie d'exécuter uniquement la partie pertinente du script. La suppression des messages d'erreur ne fait aucun pas dans cette direction. En fait, cela peut conduire à une confusion sérieuse en dépannant d' autres choses qui pourraient potentiellement se casser.
Alois Mahdal
1
J'ai commencé à utiliser cette approche peu de temps après la réponse, et cela fonctionnait parfaitement avec les sshs simples jusqu'à présent, quand j'ai commencé à le faire ssh -X--- pour pouvoir utiliser Vim sur ssh afin que le contenu sélectionné par le mode visuel parvienne au presse-papiers X local, pour lequel vous n'avez pas besoin de xserver côté serveur. DISPLAY est donc défini comme un simple effet d'activation du transfert, même si xserver et xset ne sont pas présents.
Alois Mahdal
Ce serait alors:if [[ $DISPLAY ]]; then … fi
Serge Stroobandt
1
Votre DISPLAYvariable peut pointer vers un affichage qui n'a pas réellement de serveur X en cours d'exécution (par exemple, lorsqu'il est codé en dur dans un script ou que le serveur X a été arrêté après la définition de la variable).
n.st
6

J'utilise généralement la TERMvariable pour tester X dans mes scripts.

TERMest généralement réglé linuxsur TTY et xtermsur X.
J'utilise ici le mot "habituellement", car des applications comme GNU Screen et TMux semblent jouer avec la TERMvariable.

darnir
la source
essayez echo $TERMde découvrir le paramètre richt sur votre mashine dans différentes consoles. J'utilise [ $TERM == "linux" ] && echo do some stuffsur Ubuntu
rubo77
3

Cela devrait parfaitement fonctionner:

[ ! -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.

Donc, lorsque cela est évalué à false ( [ ! -t 0 ]), nous sommes dans un environnement GUI.

terdon
la source
Avec cela, j'obtiens le même résultat à la fois dans X et dans la console, à savoir [ -t 0 ]et [ -t 1 ]sont tous les deux vrais.
Emanuel Berg
Étrange, cela fonctionne pour moi lors de la connexion à un hôte distant.
terdon
[ -t 0 ]fonctionne bien sur la console dans Ubuntu (en utilisant CTRL ALT F1)
rubo77
0

Il y a plusieurs façons de procéder.

En bash, essayez

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

Ou, en zsh, essayez

#!/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
la source
Point pris, mais testez-vous votre code avant de poster? Le premier a une erreur de syntaxe et ne détecte pas réellement si nous sommes en session X, donc echo 1si X est en cours d'exécution et que vous vous connectez via tty1-6 ou ssh. L'autre fait toujours du "non-X" - je pense que cela ${CURRENT_VT[6]}signifie plutôt 6ème ligne que 6ème caractère.
Alois Mahdal
@AloisMahdal: Aha, mes trucs ne fonctionnent pas en bash (j'utilise zsh). Je n'y ai pas pensé. Eh bien, vous pouvez l'essayer en zsh (type zsh) et éventuellement faire quelques modifications si vous l'aimez, pour le faire fonctionner en bash.
Emanuel Berg
@AloisMahdal: OK, je l'ai changé. Quant à la "connexion via tty1-6", comme c'est le cas, c'est ce que je fais, puis j'utilise la deuxième solution (ci-dessus) et définit une variable. Vérifiez cela .zshrc et recherchez export VT. J'utilise la variable pour contenir dans quel Linux VT / console / tty je suis (pour l'invite zsh) mais dans X, je le mets juste à "X" (mais pas un VT). Mais ce sont des détails, vous pouvez le calculer comme vous le souhaitez dans bash en utilisant le même principe.
Emanuel Berg
J'ai ajouté la version bash de la condition au deuxième exemple. Cependant, je pense que le premier est toujours faux. Peut-être qu'avoir ps print uniquement des ancêtres serait utile. Je ne sais pas si c'est possible, cependant.
Alois Mahdal
@AloisMahdal: Découvrez l'édition. Cela le fait pour moi, y compris les trucs tty.
Emanuel Berg
0

if [[ $DISPLAY ]]

Sur le même ordinateur, $DISPLAYon reviendra par exemple 0:0dans un émulateur de terminal, mais rien dans un vrai terminal. Cela peut facilement être testé avec CtrlAltF1versus CtrlAltF7.

Une bashcondition basée sur $DISPLAYse présenterait comme suit:

if [[ $DISPLAY ]]; then 
  
fi
Serge Stroobandt
la source