如何從腳本中識別終端?

如何從腳本中識別終端?

並且不要說「$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}'

這是我使用幾個不同的終端在系統上得到的結果:

  1. terminator

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/bin/x-terminal-emulator
    
  2. gnome-terminal

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/lib/gnome-terminal/gnome-terminal-server
    
  3. 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 個字元的命令名稱。

相關內容