获取 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

相关内容