Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Recently I put xset b off to my .bashrc. Now I'm annoyed by the error thet pops up when I log in via tty or via ssh, i.e. outside X session.

First thing that came in my mind was [[ -z "$SOME_VAR" ]] && xset b off (well, turns out that testing variable being set vs. being empty is a different question). But which SOME_VAR is the correct one?

So I diffed tty's set output and urxvt's set output to see which variables are set in X and missing in tty. As expected, there were quite many differences (listing only those that seemed relevant to me):

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

Which one is the most correct and universal one to test in order to detect if I'm in an X session or not? Something that would work across as many distros and platforms and desktop environments as possible?

Or is there even better way than testing environment variables?

share|improve this question
add comment

4 Answers

I think checking DISPLAY would be the best approach.

  • It handles remote logins (e.g. ssh -X).
  • It is available in most - if not all - platforms.
  • It is independent of window manager/DE.
share|improve this answer
2  
I'd also go for DISPLAY, or simply suppress the error message in general. Give /dev/null some love from time to time. –  frostschutz Apr 11 '13 at 23:06
1  
@frostschutz No, I'm trying to run only relevant part of script. Suppressing error messages does not make any step in that direction. In fact, it can lead to serious confusion troubleshooting other things that might potentially break. –  Alois Mahdal Apr 14 '13 at 16:10
1  
I started using this approach shortly after the answer, and it worked perfectly with simple sshs until now, when I started doing ssh -X---to be able to use Vim over ssh so that content selected by visual mode gets to local X clipboard, for which you don't need xserver on the server side. So DISPLAY gets set just as effect of simply enabling the forwarding, even if xserver and xset are not present. –  Alois Mahdal Jul 10 '13 at 23:45
add comment

I usually use the TERM variable to test for X in my scripts.

TERM is usually set to linux on TTY and xterm on X.
I use the word "usually" here, since applications like GNU Screen and TMux seem to mess with the TERM Variable.

share|improve this answer
add comment

There are many ways you could do that.

In bash, try

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

Or, in zsh, try

#!/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
share|improve this answer
    
Point taken, but do you test your code before posting? The first one has syntax error and does not actualy detect if we are in X session so it will echo 1 if X is running and you log in via tty1-6 or ssh. The other one always does "non-X stuff"--I think that ${CURRENT_VT[6]} means rather 6th line than 6th char. –  Alois Mahdal Apr 14 '13 at 16:22
    
@AloisMahdal: Aha, my stuff doesn't work in bash (I use zsh). Didn't think of that. Well, you could try it in zsh (type zsh) and possibly do some modifications if you like it, to make it work in bash. –  Emanuel Berg Apr 14 '13 at 16:28
    
@AloisMahdal: OK, I changed it. As for the "log in via tty1-6", as it happens, that's what I do, and then I use the second solution (above) and set a variable. Check out this .zshrc and search for export VT. I use the variable to hold what Linux VT/console/tty I'm in (for the zsh prompt) but in X, I just set it to "X" (although not a VT). But that's details, you could work it out any way you'd like in bash using the same principle. –  Emanuel Berg Apr 14 '13 at 16:59
    
I have added bash version of the condition to the second example. However, I think that the first one is still wrong. Maybe having ps print only ancestors would help. I'm not sure if it's possible, though. –  Alois Mahdal Apr 14 '13 at 17:10
    
@AloisMahdal: Check out the edit. That does it for me, including the tty stuff. –  Emanuel Berg Apr 14 '13 at 17:19
add comment

This should work perfectly well:

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

So, when this evaluates to false ([ ! -t 0 ]) we are in a GUI environment.

share|improve this answer
    
With this, I get the same result in both X and in the console, namely [ -t 0 ] and [ -t 1 ] are both true. –  Emanuel Berg Apr 14 '13 at 22:09
    
Strange, it works for me when sshing into a remote host. –  terdon Apr 14 '13 at 22:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.