¿Cómo puedo obtener el PID de la instancia de Terminal de GNOME activa mediante progtwigción?

¿Cómo puedo obtener el PID de la instancia de Terminal de GNOME que estoy usando desde un script Bash?

Puedo ejecutar xprop _NET_WM_PID y luego hacer clic manualmente en la ventana del terminal, pero me gustaría automatizar completamente esto.

He escrito dos funciones recursivas que rastrean a los padres de un proceso.

 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 $$ 

Lo que he encontrado en el proceso es esto:

 $ 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 

Así que podríamos usar las dos funciones y grep el gnome-terminal , asumiendo que eso es lo que el usuario quiere. Si el usuario desea algún emulador de terminal, eso puede ser problemático porque además de verificar si hay un dispositivo pts abierto, no hay forma de saber si el proceso es un emulador de terminal.

Aparte de eso, hay algo muy interesante también:

 $ 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 

Aparentemente, tmux bifurca y el proceso es recogido por init , así que nuevamente está el obstáculo.

Usando la Ayatana de Unity

El código de abajo utiliza qdbus y la interfaz dbus de Ayatana para enumerar todas las ventanas de gnome-terminal y si están enfocadas en el momento o no. Esto se puede analizar o editar posteriormente para generar solo PID de ventana activa / enfocada

Ejecución de la muestra:

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

Y el codigo en si

 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 

Hay veces en que se ejecuta más de una instancia, cuando tengo un terminal abierto en una sesión de invitado, por ejemplo

La variable $PPID le dará el proceso principal para el shell bash actual, que a menudo es gnome-terminal .

Sin embargo, para estar seguro, lo siguiente encontrará el proceso del terminal-gnome padre , incluso si se anidan múltiples shells bash:

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


La siguiente versión universal funcionará para cualquier shell, incluso si se están ejecutando otras instancias de grep. Descifrarlo se deja como un ejercicio para el lector;)

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

Esta solución me parece la más robusta. Busca recursivamente el PID principal hasta encontrar uno que pertenezca al terminal de GNOME.

 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