如何让脚本检测终端仿真器是否在桌面会话中运行?

如何让脚本检测终端仿真器是否在桌面会话中运行?

我运行脚本来写出一个文本文件,然后在编辑器中打开它。如果我在桌面会话中打开终端仿真器窗口并运行脚本,我希望编辑器是图形编辑器,例如gedit。但是,如果我通过手机上的 ConnectBot 或类似设备登录(没有桌面会话),我希望编辑器是nano

目前我必须维护 2 个不同的脚本,除了最后一步之外完全相同(或者让图形脚本运行,关闭错误,然后手动打开文件nano)。从维护的角度来看,拥有两个几乎相同的脚本是低效的。

脚本能否检测我处于哪种情况并打开正确的编辑器?

(我已经找到了一种让脚本检测它是在终端仿真器窗口中运行还是通过双击运行的方法,但还没有找到一种检测窗口是否在桌面上运行的方法……我想我不知道该用谷歌搜索正确的术语)

答案1

您可以使用环境变量$DISPLAY作为if条件内的触发器。通常,当此变量有值时,您就可以运行图形应用程序。

这里有一个例子:

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

-z当环境变量为空时,运算符将返回 true$DISPLAY并且脚本将运行nano,在所有其他情况下它都会运行gedit


根据此评论@vurp0

在大多数现代 Wayland 桌面上(例如 Fedora 和 Ubuntu 中的默认桌面),$DISPLAY由于向后兼容(通过 XWayland)仍然设置,但对于更强大的脚本,最好对两者进行测试$DISPLAY$WAYLAND_DISPLAY确保万无一失。

我建议按以下方式修改测试表达式:

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

因此,两个变量的值将连接成一个公共字符串,并由运算符进行处理-z


参考:

答案2

通常虚拟终端使用/dev/pts伪终端。因此,基于tty命令的输出,我们可以构建一个简单的case语句来处理打开特定的编辑器:

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

或者格式更漂亮:

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

与使用环境变量相比,这种方法更可靠,而且考虑到它使用case语句和tty命令,这种方法更易于移植。最好的方法可能是将两者结合起来,并进行额外的测试,例如"/dev/tty"*) [ -n "$DISPLAY" ] && gedit ;;

答案3

这是我一直在使用的:

# $TERM variable may be missing when called via desktop shortcut
CurrentTERM=$(env | grep TERM)
if [[ $CurrentTERM == "" ]] ; then
    notify-send --urgency=critical "$0 cannot be run from GUI without TERM environment variable."
    exit 1
fi

这段代码的原因是这个问题:Bash 脚本的桌面快捷方式崩溃并烧毁

您可以将其修改为如下所示:

# $TERM variable may be missing when called via desktop shortcut
CurrentTERM=$(env | grep TERM)
if [[ $CurrentTERM == "" ]] ; then
    nano ...
else
    gedit ...
fi

相关内容