如何以编程方式获取活动GNOME终端实例的PID?

如何在Bash脚本中获取我正在使用的GNOME Terminal实例的PID?

我可以运行xprop _NET_WM_PID ,然后手动单击终端窗口,但我想完全自动执行此操作。

我写了两个递归函数来跟踪进程的父进程

 get_parent() { ps --no-headers -p $1 -o ppid,cmd } process_list() { if [ "$1" -ne "1" ]; then PARENT="$(get_parent $1 )" printf "%s\n" "$PARENT" process_list $( printf "%s" "$PARENT" | awk '{print $1}' ) fi } print_header() { printf "PPID\tPROCESS\n" for i in $(seq 1 20 ) do printf "-" done printf "\n" } print_header process_list $$ 

我在这个过程中发现的是:

 $ bash get_process_list PPID PROCESS -------------------- 31264 bash get_process_list 31251 mksh 16696 gnome-terminal 15565 /bin/mksh 2164 x-terminal-emulator 1677 init --user 1342 lightdm --session-child 12 19 1 lightdm 

所以我们可以使用这两个函数并grep gnome-terminal ,假设这是用户想要的。 如果用户想要任何终端仿真器,那可能会有问题,因为除了检查lsof是否打开pts设备之外,没有办法判断该进程是否是终端仿真器。

除此之外,还有一些非常有趣的事情:

 $ bash get_process_list PPID PROCESS -------------------- 32360 bash get_process_list 23728 -mksh 2164 tmux 1677 init --user 1342 lightdm --session-child 12 19 1 lightdm 

tmux显然是自己分叉,并且进程被 init ,所以再次出现了障碍。

使用Unity的Ayatana

下面的代码使用qdbus和Ayatana的dbus接口来列出所有gnome-terminal窗口,以及它们是否现在都是焦点。 这可以在以后解析或编辑,以仅输出活动/聚焦窗口PID

样品运行:

 $ bash get_gt_pd.sh XID:33554486 PID:20163 ACTIVE:true XID:33554444 PID:20163 ACTIVE:false 

而代码本身

 get_gt_xid() { # Prints XID of each gnome-terminal window qdbus --literal org.ayatana.bamf \ /org/ayatana/bamf/matcher \ org.ayatana.bamf.matcher.XidsForApplication \ /usr/share/applications/gnome-terminal.desktop } for window in $(get_gt_xid | awk -F'{' '{ gsub(/\,|}|]/," ");print $2 }' ) do PID=$(qdbus org.ayatana.bamf /org/ayatana/bamf/window/"$window"\ org.ayatana.bamf.window.GetPid) ACTIVE=$( qdbus org.ayatana.bamf /org/ayatana/bamf/window/"$window"\ org.ayatana.bamf.view.IsActive ) printf "XID:%s\tPID:%s\tACTIVE:%s\n" "$window" "$PID" "$ACTIVE" done 

有时会运行多个实例 – 例如,当我在访客会话中打开终端时

变量$PPID将为您提供当前bash shell的父进程,该进程通常是gnome-terminal

但是为了安全起见,即使嵌套了多个bash shell,以下内容也会找到 gnome-terminal进程:

pstree -p -s $PPID | grep -Po 'gnome-terminal\(\K.*?(?=\))'


以下通用版本适用于任何shell,即使其他grep实例正在运行。 解读它是留给读者的练习;)

 pstree -p -a -s \
 $(pstree -p -a | grep -B3 $ RANDOM $ RANDOM \
 |  grep -m1`echo $ SHELL | cut -d / -f3` | 切-d,-f2)
 |  grep gnome-terminal |  cut -d,-f2

这个解决方案对我来说是最强大的。 它递归地查找父PID,直到找到属于GNOME终端的PID。

 find-parent() { i=($(ps -o pid= -o ppid= -o cmd= -p $1)) ((i[0] == 1)) && return 1 if [[ ${i[2]} =~ (^|/)gnome-terminal$ ]]; then echo ${i[0]}; else find-parent ${i[1]}; fi }; find-parent $PPID