Rilevamento della sessione X in uno script bash (.bashrc ecc.)


16

Recentemente ho messo xset b offsul mio .bashrc. Ora sono infastidito dall'errore che viene visualizzato quando eseguo l'accesso tramite tty o tramite ssh, ovvero all'esterno della sessione X.

La prima cosa che mi è venuta in mente è stata [[ -z "$SOME_VAR" ]] && xset b off(beh, si scopre che la variabile test impostata su essere vuota è una domanda diversa). Ma quale SOME_VAR è quello corretto?

Quindi ho differito l' setoutput di tty e l' setoutput di urxvt per vedere quali variabili sono impostate in X e mancanti in tty. Come previsto, c'erano molte differenze (elencando solo quelle che mi sembravano rilevanti):

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

Qual è il più corretto e universale da testare per rilevare se sono in una sessione X o no? Qualcosa che funzionerebbe su quante più distro e piattaforme e ambienti desktop possibili?

O esiste un modo persino migliore di testare le variabili di ambiente?

Risposte:


8

Un modo semplice ed efficace per verificare che il tuo server di visualizzazione sia disponibile e valido è testarlo con xhost. Non puoi sempre fare affidamento sul controllo di un valore nella DISPLAYvariabile poiché potrebbe essere impostato con un valore non valido.

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

Il motivo per cui lo faccio è perché eseguo diversi script nel mio utente crontabche operano sul display quando esiste, ma funzionano diversamente quando no. Nella parte superiore della mia crontab, ho impostato la DISPLAYvariabile :0anche se non esiste ancora. Gli script crontabche iniziano con @rebootinizieranno indipendentemente dal fatto che tu abbia o meno un display. Ciò ti consentirà di rilevare dinamicamente quando il tuo display entra e esce all'interno dello stesso script.

NOTA: >&funziona solo in bash> = 4. In caso contrario, utilizzare> /dev/null 2>&1


Bello, testato anche con ssh -X; funziona bene!
Alois Mahdal,

13

Penso che il controllo DISPLAYsarebbe l'approccio migliore.

  • Gestisce accessi remoti (es. Ssh -X).
  • È disponibile nella maggior parte - se non in tutte - le piattaforme.
  • È indipendente dal gestore delle finestre / DE.

2
Vorrei anche cercare DISPLAY, o semplicemente sopprimere il messaggio di errore in generale. Dai un /dev/nullpo 'd'amore di tanto in tanto.
frostschutz,

3
@frostschutz No, sto cercando di eseguire solo una parte rilevante dello script. La soppressione dei messaggi di errore non fa alcun passo in quella direzione. In realtà, può portare a seria confusione nella risoluzione di altri problemi che potrebbero potenzialmente rompersi.
Alois Mahdal,

1
Ho iniziato a utilizzare questo approccio poco dopo la risposta, e ha funzionato perfettamente con semplici sshs fino ad ora, quando ho iniziato a fare ssh -X--- per essere in grado di usare Vim su ssh in modo che il contenuto selezionato dalla modalità visiva arrivi negli Appunti X locali, per il quale non è necessario xserver sul lato server. Quindi DISPLAY viene impostato proprio come l'effetto di abilitare semplicemente l'inoltro, anche se xserver e xset non sono presenti.
Alois Mahdal,


1
La tua DISPLAYvariabile può puntare a un display che in realtà non ha un server X in esecuzione (ad esempio quando è hardcoded in uno script o il server X è stato spento dopo l'impostazione della variabile).
n.

6

Di solito uso la TERMvariabile per verificare X nei miei script.

TERMdi solito è impostato linuxsu TTY e xtermsu X.
Uso qui la parola "solito", poiché applicazioni come GNU Screen e TMux sembrano confondere con la TERMvariabile.


prova echo $TERMa scoprire l'impostazione richt sul tuo mashine in diverse console. Uso [ $TERM == "linux" ] && echo do some stuffsu Ubuntu
rubo77

3

Questo dovrebbe funzionare perfettamente:

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

Quindi, quando questo restituisce false ( [ ! -t 0 ]) ci troviamo in un ambiente GUI.


Con questo, ottengo lo stesso risultato sia in X che nella console, vale a dire [ -t 0 ]e [ -t 1 ]sono entrambi veri.
Emanuel Berg,

Strano, funziona per me quando metto un host remoto.
terdon

[ -t 0 ]funziona bene sulla console in Ubuntu (usando CTRL ALT F1)
rubo77

0

Ci sono molti modi per farlo.

In bash, prova

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

Oppure, in zsh, prova

#!/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

Punto preso, ma testate il codice prima di pubblicare? Il primo ha un errore di sintassi e in realtà non rileva se siamo nella sessione X, quindi lo farà echo 1se X è in esecuzione e accedi tramite tty1-6 o ssh. L'altro fa sempre "cose ​​non-X" - penso che ${CURRENT_VT[6]}significhi piuttosto la sesta riga che il sesto carattere.
Alois Mahdal,

@AloisMahdal: Ah, la mia roba non funziona in bash (io uso zsh). Non ci ho pensato. Bene, potresti provarlo in zsh (tipo zsh) e possibilmente fare alcune modifiche se ti piace, per farlo funzionare in bash.
Emanuel Berg,

@AloisMahdal: OK, l'ho cambiato. Per quanto riguarda il "login via tty1-6", come succede, è quello che faccio, quindi uso la seconda soluzione (sopra) e imposto una variabile. Dai un'occhiata a questo .zshrc e cerca export VT. Uso la variabile per contenere in quale VT / console / tty di Linux mi trovo (per il prompt di zsh) ma in X l'ho appena impostato su "X" (sebbene non sia un VT). Ma questo è il dettaglio, potresti risolverlo come vuoi in bash usando lo stesso principio.
Emanuel Berg,

Ho aggiunto la versione bash della condizione al secondo esempio. Tuttavia, penso che il primo sia ancora sbagliato. Forse avere ps print solo gli antenati sarebbe d'aiuto. Non sono sicuro che sia possibile, però.
Alois Mahdal,

@AloisMahdal: controlla la modifica. Lo fa per me, compresa la roba tty.
Emanuel Berg,

0

if [[ $DISPLAY ]]

Sullo stesso computer, $DISPLAYtornerà ad esempio 0:0in un emulatore di terminale, ma nulla in un terminale reale. Questo può essere facilmente testato con CtrlAltF1versus CtrlAltF7.

Una bashcondizione basata su $DISPLAYdovrebbe apparire come segue:

if [[ $DISPLAY ]]; then 
  
fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.