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)
是否有我可能缺少的简单通用解决方案?或者我除了搜索二进制文件以获取提示或使用硬编码列表之外别无他法?
你的启发法非常糟糕。这是他们在我的 Debian 机器上找到的内容(我已经用 手动标记了正确的命中+
)。
/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 机器上的正确答案(就发行版管理的程序而言):
/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\n15 个中你会找到 7 个(考虑到名字的变化),这并不是一个很好的命中率。
\n\n您可以尝试完善您的启发式方法,但这是一场永无止境的游戏。最低限度是只保留链接到某些 X11 库并调用某些主终端函数或实用程序(如getpt
或 )的可执行文件grantpt
,但这也必然会发现很多虚假的肯定,并且会错过调用所在的可执行文件一个图书馆(如konsole
)。这将错过通过 shell 包装器访问的本机代码可执行文件(我的列表中有几个)。
从可执行内容中检测程序是否是 X 终端模拟器是没有希望的。
\n\n按名称检测程序是一种更好的启发式方法。
\n\n另请注意,不同的程序具有不同的命令行语法。它们中的大多数接受和,但它们有不同的解析规则(是否通过 shell,是否接受多个参数),因此您应该在 后传递一个参数,不包含任何 shell 特殊字符。-T TITLE
-e COMMAND
-e
-e
在 Debian 及其衍生版本上,x-terminal-emulator
保证是一个支持-T
和的 X 终端模拟器-e
,这样-e
可以使用所有后续命令行参数作为命令及其参数,并且不会对它们进行 shell 扩展。因为某些模拟器的行为不同,x-terminal-emulator
有时是一个包装器,它采用更类似于 xterm 的语法(gnome-terminal.wrapper
和xfce4-terminal.wrapper
是这方面的两个例子)。
我不知道其他 UNIX 变体上有类似的情况。对于可移植性之类的任何事情,硬编码的程序名称列表是最好的选择。
\n\n此外,检测已安装的终端模拟器不会让您了解用户的偏好。例如,如果我使用 Gnome,我可能不希望您的应用程序启动 Konsole \xe2\x80\x94\xc2\xa0,除非我碰巧更喜欢 Konsole,但你怎么知道呢?
\n\n用户首选项的事实标准是通过FreeDesktop.org规范实现的。Freedesktop 发布了一个xdg-utils
程序包,其中包含诸如xdg-open
在适当的应用程序中打开文档、xdg-email
启动用户首选的电子邮件撰写应用程序等程序xdg-terminal
用户首选的终端模拟器等程序。
这将是xdg-terminal
正确的使用方式,如果有的话你应该使用它。不幸的是,xdg-terminal
并非所有地方都可用;例如,Debian 不提供它(这是一个长期闲置的错误)。此外xdg-terminal
允许单个命令参数,并且该参数所经历的扩展类型并不一致。
无论您做什么,请确保为呼叫者提供一种简单的方法来指定首选项。甚至xdg-terminal
并不总是正确的。
因此,你的最佳策略是:
\n\nxdg-terminal
x-terminal-emulator