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 ;;