取得 shell 腳本中的終端模擬器名稱

取得 shell 腳本中的終端模擬器名稱

我曾經pstree使用類似以下內容來尋找執行 shell 腳本的父模擬器的名稱:

pstree -s $PPID | awk -F '---' '{print $6}'

這適用於我目前的系統。我測試過mate-terminalxterm但不確定這是否適用於其他 Linux 系統/平台和其他終端。有沒有更好/更整潔(更便攜的方式)的方法來實現這一目標?

答案1

ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$$")))")))"

可能會為你帶來好的結果。它給出了會話領導者的父進程的名稱。對於在終端模擬器中啟動的進程,通常是運行該終端模擬器的進程(除非使用諸如screenexpect、 ... 之類的東西(但請注意和tmuxscreentmux setsid終端模擬器),或使用, start-stop-daemon...)明確啟動新會話

或者使用變數將其分解為單獨的步驟(這也可以幫助使腳本更加不言自明):

sid=$(ps -o sid= -p "$$")
sid_as_integer=$((sid)) # strips blanks if any
session_leader_parent=$(ps -o ppid= -p "$sid_as_integer")
session_leader_parent_as_integer=$((session_leader_parent))
emulator=$(ps -o comm= -p "$session_leader_parent_as_integer")

這裡數字周圍的空白的剝離是使用$((...))算術擴展完成的。您也可以使用 split+glob 運算子(假設未修改$IFS)或按照 @ack 在註解中的建議使用xargs

ps -o sid= -p "$$" |
  xargs ps -o ppid= -p |
  xargs ps -o comm= -p

您也可以嘗試解析wtmp終端模擬器通常記錄的條目及其與偽終端設備關聯的 pid。如果不涉及expect/screen/tmux...,這在 Debian 系統上適用於我:

ps -o comm= -p "$(
  dump-utmp -r /var/log/wtmp |
  awk -v tty="$(ps -o tty= -p "$$")" -F ' *\\| *' '
    $2 == tty {print $5;exit}')"

(來自dump-utmpGNU acct)。

答案2

若要尋找目前 shell 使用的終端機模擬器的名稱,您可以要求 X 視窗系統提供目前 shell 可見的視窗的名稱:

$ xwininfo -id $WINDOWID | awk '/^xwin/ { print $NF }'

當我在 Rxvt-unicode 中運行時,這會"xterm"在 XTerm 中傳回字串。"urxvt"如果您有更改視窗標題的習慣,結果可能會有所不同,因為我認為這就是這裡返回給您的內容。

答案3

建立在史蒂芬·查澤拉斯使其在 tmux 下工作的解決方案(即返回 tmux 用戶端用於顯示的終端模擬器),這似乎對我有用:

TERMINAL_EMULATOR="$(ps --pid $(ps --pid $$ -o ppid=) -o comm=)"
if [[ "${TERMINAL_EMULATOR}" =~ tmux ]]; then
    export TERMINAL_EMULATOR=$(ps --pid "$(($(ps --pid $(ps --pid $(tmux display-message -p "#{client_pid}") -o sid=) -o ppid=)))" -o comm=)
else
    export TERMINAL_EMULATOR
fi

相關內容