並且不要說「$TERM
」——總是如此xterm
。
腳本如何bash
知道它正在哪個終端機運行,特別是它是 iTerm、Terminal.app 還是實際上的 xterm?
我問這個問題是因為reset
在 Terminal.app 和 iTerm2 上無法開箱即用。然而,iTerm2 確實可以識別用於執行終端重置 ( ) 的轉義序列\x1b]50;ClearScrollback\x07
,如果我可以檢測到它,我可以reset
使用執行正確操作的別名進行覆蓋。 AFAICT,Terminal.app 缺少重置序列,並且人們訴諸可笑的湯姆黑客來解決這個問題。
reset
我的最終目標是無論是在 OS X 還是 Linux 上工作、透過 SSH 在本地或遠端工作,都能實現相同的工作。 (我不想嘗試記住哪一個,而且進行reset && command-that-outputs-a-bunch
輸入工作很有用。) Terminal.app 和 iTerm 由於沒有reset
正確實施而破壞了這個計劃。
這意味著簡單的覆蓋reset
並不完全是這樣:如果我在 Linux 機器上,它需要知道我正在使用gnome-terminal
還是 iTerm 才能發送正確的轉義序列。
有什麼辦法(即使我需要ioctl
)詢問終端它是什麼真的是?
1就本問題而言,重置應清除螢幕、重設遊標並擦除回滾緩衝區。
答案1
使用$TERM_PROGRAM
。
iTerm 將其設定為iTerm.app
,Terminal.app 設定為Apple_Terminal
。
答案2
$TERM
與目前運行的終端模擬器無關,它只是您的預設終端,可以設定為任何內容。若要取得正在執行的終端模擬器的名稱,可以使用ps
取得目前 shell 的父進程的 PID。
注意:以下操作在 OSX 上會失敗,但在 Linux 上應該可以正常運作
目前 shell 進程的 PID 是$$
。從那裡,您可以用來ps
顯示進程樹,並列印目前 shell 會話的父進程的 PID:
ps -axjf | awk -v pid=$$ '($2==pid){print $1}'
然後,您可以將該 PID 傳遞給ps
並告訴它列印命令名稱:
ps -o comm= $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')
這將截斷名稱,它應該足以讓您弄清楚它,但可能不利於編寫腳本。要獲得完整名稱,您可以嘗試
ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'
這是我使用幾個不同的終端在系統上得到的結果:
terminator
$ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}' /usr/bin/x-terminal-emulator
gnome-terminal
$ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}' /usr/lib/gnome-terminal/gnome-terminal-server
xterm
$ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}' xterm
答案3
這是取得父進程的名稱或路徑的可移植方法:
i學期 2:
$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm
Ubuntu 中的 gnome 終端機:
$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal
終端.應用程式:
$ ps -p $(ps -p $$ -o ppid=) -o comm=
login
請注意,如果 Terminal.app 設定為使用預設登入 shell 開啟新 shell,則 shell 的父進程是login
而不是終端。
該comm
列是 OS X 中命令的完整路徑,以及 Linux 中 procps 實作中被截斷為 15 個字元的命令名稱。