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

use*_*000 5 terminal-emulator shell-script portability

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

我看过这个线程。但是,我并不是很倾向于进行硬编码检查,我正在寻找通用解决方案。

我提出了这个非常肮脏的黑客,但我真的不确定这会如何:

termdetect

#!/bin/bash

IFS=:
for i in $PATH; do
  find "$i" -type f -exec isterminal {} \;
done
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

Gil*_*il' 3

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

\n\n
/usr/bin/gcm-calibrate\n/usr/bin/gnome-terminal        +\n/usr/bin/mosh-client   \n/usr/bin/mosh-server\n/usr/bin/mrxvt                 +\n/usr/bin/mrxvt-full            +\n/usr/bin/roxterm               +\n/usr/bin/rxvt-unicode          +\n/usr/bin/urxvt                 +\n/usr/bin/urxvtd\n/usr/bin/vinagre\n/usr/bin/x-terminal-emulator   +\n/usr/bin/xfce4-terminal        +\n/usr/bin/xterm                 +\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n
/usr/bin/Eterm\n/usr/bin/gnome-terminal.wrapper\n/usr/bin/koi8rxterm\n/usr/bin/konsole\n/usr/bin/lxterm\n/usr/bin/mlterm\n/usr/bin/mrxvt-full\n/usr/bin/roxterm\n/usr/bin/rxvt-xpm\n/usr/bin/rxvt-xterm\n/usr/bin/urxvt\n/usr/bin/uxterm\n/usr/bin/xfce4-terminal.wrapper\n/usr/bin/xterm\n/usr/bin/xvt\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

用户首选项的事实标准是通过FreeDesktop.org规范实现的。Freedesktop 发布了一个xdg-utils程序包,其中包含诸如xdg-open在适当的应用程序中打开文档、xdg-email启动用户首选的电子邮件撰写应用程序等程序xdg-terminal用户首选的终端模拟器等程序。

\n\n

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

\n\n

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

\n\n

因此,你的最佳策略是:

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