How to have script detect if terminal emulator is running in a desktop session or not?

I have scripts I run that write out a text file, then open it in an editor. If I open a terminal emulator window in my desktop session and run the script, I'd like the editor to be a graphical one such as gedit. But, if I'm logged in through ConnectBot on my phone or similar (no desktop session), I'd like the editor to be nano.

Currently I have to maintain 2 different scripts, identical except for the last step (or let the graphical one run, error off, then manually open the file in nano). Having two mostly identical scripts is inefficient from a maintenance standpoint.

Can a script detect which of these situations I'm in, and open the correct editor?

(I have found ways for a script to detect whether it's running in a terminal emulator window or by being double-clicked, but not yet found a way to detect if the window is running in a desktop...I don't think I know the correct terminology to google for)


You can use the environment variable $DISPLAY as trigger within a if condition. Usually when this variable has a value you are able to run graphical applications.

Here is a bash example:

if [[ -z $DISPLAY ]]
then
    nano
else
    gedit
fi

The operator -z will return true when the envvar $DISPLAY is empty and your script will run nano, in all other cases it will run gedit.


According to the this comment of @vurp0:

On most modern Wayland desktops (like the default desktop in Fedora and Ubuntu), $DISPLAY is still set due to backwards compatibility (through XWayland), but for a more robust script it would be good to test for both $DISPLAY and $WAYLAND_DISPLAY to be sure.

I would suggest to modify the test expression in the following way:

[[ -z ${DISPLAY}${WAYLAND_DISPLAY} ]]

Thus, the values of the two variables will be concatenated into a common string, which will be processed by the operator -z.


References:

  • Advanced Bash-Scripting Guide: 7. Tests
  • Advanced Bash-Scripting Guide: 7.1. Test Constructs
  • Advanced Bash-Scripting Guide: 7.3. Other Comparison Operators

Typically virtual terminals use /dev/pts pseudo-terminals. So, based on the output of tty command, we can build a simple case statement to handle opening particular editor:

case "$(tty)" in ; "/dev/pts"*) nano ;; "/dev/tty"*) gedit ;; ;esac

Or formatted more nicely:

case "$(tty)" in
    "/dev/pts"*) gedit ;; 
    "/dev/tty"*) nano ;;
    *) echo "Not suitable tty" > /dev/stderr ;;
esac

Compared to using environment variables, this is slightly more reliable and considering it uses case statement with tty command slightly more portable. What probably would be best is to combine both, with extra testing, such as "/dev/tty"*) [ -n "$DISPLAY" ] && gedit ;;