在不知道安装了哪些终端模拟器的情况下启动终端模拟器

在不知道安装了哪些终端模拟器的情况下启动终端模拟器

我需要编写一个脚本来启动终端模拟器并在其中运行特定命令。由于我不知道目标系统上安装了哪些终端模拟器,因此如何找到已安装哪些终端模拟器?

我看过这个线程。但是,我不太愿意进行硬编码检查,并且我正在寻找通用的解决方案。

我已经想到了这个非常肮脏的黑客,但我真的不确定这会如何:

termdetect:

#!/bin/bash

IFS=:
for i in $PATH; do
  find "$i" -type f -exec isterminal {} \;
done

isterminal:

#!/bin/bash

if [[ ! -z "$1" ]]; then
  if [[ "$(head -c 4 "$1")" == $'\x7fELF' ]]; then
    if ! grep editor "$1" > /dev/null; then
      if grep -E '(vte_terminal_|libutempter|rxvt_)' "$1" > /dev/null; then
        echo "$1"
      fi
    fi
  fi
fi

我可能缺少一个简单的通用解决方案吗?或者除了搜索二进制文件以获取提示或使用硬编码列表之外我没有其他方法吗?

答案1

你的启发法非常糟糕。这是他们在我的 Debian 机器上找到的内容(我已经用 手动标记了正确的命中+)。

/usr/bin/gcm-calibrate
/usr/bin/gnome-terminal        +
/usr/bin/mosh-client   
/usr/bin/mosh-server
/usr/bin/mrxvt                 +
/usr/bin/mrxvt-full            +
/usr/bin/roxterm               +
/usr/bin/rxvt-unicode          +
/usr/bin/urxvt                 +
/usr/bin/urxvtd
/usr/bin/vinagre
/usr/bin/x-terminal-emulator   +
/usr/bin/xfce4-terminal        +
/usr/bin/xterm                 +

如果您选择第一个字母匹配项,则它是颜色校准器。

以下是 的替代方案列表x-terminal-emulator,这是这台 Debian 机器上的正确答案(就发行版管理的程序而言):

/usr/bin/Eterm
/usr/bin/gnome-terminal.wrapper
/usr/bin/koi8rxterm
/usr/bin/konsole
/usr/bin/lxterm
/usr/bin/mlterm
/usr/bin/mrxvt-full
/usr/bin/roxterm
/usr/bin/rxvt-xpm
/usr/bin/rxvt-xterm
/usr/bin/urxvt
/usr/bin/uxterm
/usr/bin/xfce4-terminal.wrapper
/usr/bin/xterm
/usr/bin/xvt

15 个中你会找到 7 个(考虑到名字的变化),这并不是一个很好的命中率。

你可以尝试改进你的启发式方法,但这是一个永无止境的游戏。最低限度是只保留链接到某些 X11 库并调用某些主终端函数或实用程序(如getpt或 )的可执行文件grantpt,但这也必然会发现很多虚假的肯定,并且会错过调用在库中的可执行文件(喜欢konsole)。这将错过通过 shell 包装器访问的本机代码可执行文件(我的列表中有几个)。

从可执行内容中检测程序是否是 X 终端模拟器是没有希望的。

按名称检测程序是一种更好的启发式方法。

另请注意,不同的程序具有不同的命令行语法。它们中的大多数接受和,但它们有不同的解析规则(是否通过 shell,是否接受多个参数),因此您应该在 后传递一个参数,不包含任何 shell 特殊字符。-T TITLE-e COMMAND-e-e

在 Debian 及其衍生产品上,x-terminal-emulator保证是支持-T和的 X 终端模拟器-e,这样-e使用所有后续命令行参数作为命令及其参数,并且不对它们进行 shell 扩展。因为某些模拟器的行为不同,x-terminal-emulator有时是一个包装器,它采用更类似于 xterm 的语法(gnome-terminal.wrapperxfce4-terminal.wrapper是这方面的两个例子)。

我不知道其他 UNIX 变体有类似的情况。对于可移植性之类的任何事情,硬编码的程序名称列表是最好的选择。

此外,检测已安装的终端模拟器不会让您了解用户的偏好。例如,如果我使用 Gnome,我可能不希望您的应用程序启动 Konsole — 除非我碰巧更喜欢 Konsole,但您怎么知道这一点呢?

用户偏好的事实上的标准是通过自由桌面网规格。 Freedesktop 发布了xdg-utils包中包含诸如xdg-open在正确的应用程序中打开文档,xdg-email启动用户首选的电子邮件撰写应用程序,等等xdg-terminal打开用户首选的终端模拟器。

这将是xdg-terminal正确的使用方式,如果有的话你应该使用它。不幸的是,xdg-terminal并非所有地方都可用;例如,Debian 不提供它(它是长时间闲置的错误)。此外xdg-terminal允许单个命令参数,并且该参数所经历的扩展类型不一致。

无论您做什么,请确保为呼叫者提供一种简单的方法来指定首选项。即使xdg-terminal并不总是正确的。

因此,你最好的策略是:

  1. 如果用户指定了偏好,则使用它
  2. 否则尝试xdg-terminal
  3. 否则尝试x-terminal-emulator
  4. 否则尝试硬编码列表

答案2

在 Debian 及其衍生版本(Ubuntu、Mint 等)上,x-terminal-emulator始终会启动管理员的默认图形终端。
您甚至可以包含类似的内容来确定它是否是图形会话:

if [ -z "$XAUTHORITY" ]
then 
 echo "Failed to launch terminal emulator! This is not a graphical session."
else
 x-terminal-emulator
fi

相关内容