我需要編寫一個腳本來啟動終端模擬器並在其中執行特定命令。由於我不知道目標系統上安裝了哪些終端模擬器,因此如何找到已安裝哪些終端模擬器?
我看過這個線程。但是,我不太願意進行硬編碼檢查,並且我正在尋找通用的解決方案。
我已經想到了這個非常骯髒的黑客,但我真的不確定這會如何:
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
保證是一個支援 和 的 X 終端模擬器-T
,-e
這樣-e
使用所有後續命令列參數作為命令及其參數,並且不對它們進行 shell 擴展。因為某些模擬器的行為不同,x-terminal-emulator
有時是一個包裝器,它採用更類似 xterm 的語法(gnome-terminal.wrapper
和xfce4-terminal.wrapper
是這方面的兩個例子)。
我不知道其他 UNIX 變體有類似的情況。對於可移植性之類的任何事情,硬編碼的程式名稱清單是最好的選擇。
此外,偵測已安裝的終端模擬器不會讓您了解使用者的偏好。例如,如果我使用 Gnome,我可能不希望您的應用程式啟動 Konsole — 除非我碰巧更喜歡 Konsole,但您怎麼知道這一點呢?
使用者偏好的事實上的標準是透過自由桌面網規格。 Freedesktop 發布了xdg-utils
包中包含諸如xdg-open
在正確的應用程式中開啟文檔,xdg-email
啟動用戶首選的電子郵件撰寫應用程序,等等xdg-terminal
開啟使用者首選的終端模擬器。
這將是xdg-terminal
正確的使用方式,如果有的話你應該使用它。不幸的是,xdg-terminal
並非所有地方都可用;例如,Debian 不提供它(它是長時間閒置的錯誤)。另外xdg-terminal
允許單一命令參數,且該參數所經歷的擴展類型不一致。
無論您做什麼,請確保為呼叫者提供一種簡單的方法來指定首選項。即使xdg-terminal
並不總是正確的。
因此,你最好的策略是:
- 如果使用者指定了偏好,則使用它
- 否則嘗試
xdg-terminal
- 否則嘗試
x-terminal-emulator
- 否則嘗試硬編碼列表
答案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