
我曾經pstree
使用類似以下內容來尋找執行 shell 腳本的父模擬器的名稱:
pstree -s $PPID | awk -F '---' '{print $6}'
這適用於我目前的系統。我測試過mate-terminal
,xterm
但不確定這是否適用於其他 Linux 系統/平台和其他終端。有沒有更好/更整潔(更便攜的方式)的方法來實現這一目標?
答案1
ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$$")))")))"
可能會為你帶來好的結果。它給出了會話領導者的父進程的名稱。對於在終端模擬器中啟動的進程,通常是運行該終端模擬器的進程(除非使用諸如screen
、expect
、 ... 之類的東西(但請注意和tmux
screen
tmux
是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-utmp
GNU 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