Shell-Script

在不知道安裝了哪些終端仿真器的情況下啟動終端仿真器

  • June 19, 2014

我需要編寫一個腳本來啟動終端模擬器並在其中執行特定命令。由於我不知道目標系統上安裝了哪些終端仿真器,我如何才能找到安裝了哪些終端仿真器?

我看過這個執行緒。但是,我不太傾向於進行硬編碼檢查,我正在尋找一個通用的解決方案。

我想出了這個非常骯髒的黑客,但我真的不確定這會如何:

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

是否有我可能缺少的簡單通用解決方案?或者我除了搜尋二進製文件以獲取提示或使用硬編碼列表之外別無他法?

你的啟發式方法很糟糕。這是他們在我的 Debian wheezy 機器上找到的內容(我已經手動用 標記了正確的命中+)。

/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                 +

如果您選擇第一個字母匹配,它是一個顏色校準器。

以下是 Debian 機器上的替代列表x-terminal-emulator,這是正確的答案(就分發管理程序而言):

/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 庫並呼叫某些主終端函式或實用程序(如getptor grantpt)的執行檔,但這也必然會發現很多虛假的積極因素,並且會錯過呼叫在庫中的執行檔(像konsole)。這將錯過通過外殼包裝器訪問的本機程式碼執行檔(我的列表中有幾個)。

從可執行內容中檢測程序是否是X終端仿真器是沒有希望的。

按名稱檢測程序是一種更好的啟發式方法。

另請注意,不同的程序具有不同的命令行語法。它們中的大多數都接受and ,但它們有不同的解析規則(是否通過 shell,是否接受多個參數),因此您應該在 之後傳遞單個參數,不包含任何 shell 特殊字元。-T *TITLE*``-e *COMMAND*``-e``-e

在 Debian 和衍生產品上,x-terminal-emulator保證是一個支持-Tand的 X 終端仿真器-e,這樣它將-e所有後續命令行參數用作命令及其參數,並且不對它們進行 shell 擴展。因為一些模擬器的行為不同,x-terminal-emulator有時是一個包裝器,它採用更類似於 xterm 的語法(gnome-terminal.wrapper並且xfce4-terminal.wrapper是這方面的兩個例子)。

我不知道其他 unix 變體上有這樣的事情。對於諸如可移植性之類的任何事情,程序名稱的硬編碼列表是您最好的選擇。

此外,檢測已安裝的終端仿真器不會讓您了解使用者的偏好。例如,如果我使用 Gnome,我可能不希望您的應用程序啟動 Konsole — 除非我碰巧更喜歡 Konsole,但您怎麼知道呢?

使用者偏好的事實標準是通過FreeDesktop.org規範。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. 否則嘗試硬編碼列表

引用自:https://unix.stackexchange.com/questions/137782