Cómo detectar el número de terminales abiertas por el usuario


9

Estoy usando Ubuntu y puedo cambiar manualmente el bashcolor del indicador de shell a verde usando

export PS1="\e[0;32m[\u@\h \W]\$ \e[m" 

Sin embargo, quiero que el color del indicador de shell cambie automáticamente cada vez que abra una nueva terminal o pestaña. Soy consciente de que el tty TERM básico tiene 16 colores, y está bien rotar los colores si hay más de 16 terminales abiertos. ¿Funcionará también la solución cuando me conecte Putty, tmuxo screen?

Mi idea es escribir un script de shell y colocarlo en el .bashrcque detecte la nueva sesión de terminal que el usuario ha abierto e incremente un contador global de \e[0;31m[a \e[0;47m[. ¿Cómo detectar el número de terminales abiertas por el usuario?

Respuestas:


8

Si realmente necesita obtener el número de terminales que tiene abiertos, vaya a contar los archivos que posee /dev/pts(aunque esto podría incluir los abiertos por procesos en segundo plano, no por emuladores gráficos de terminales). Alternativamente, cuente el número de procesos secundarios de su (s) emulador (es) de terminal, como lo muestra Jacob en la primera línea de su respuesta.

Evite confiar en whoel resultado de la búsqueda y buscar gnome-pty-helperprocesos, ya que estos no funcionan en gnome-terminalversiones más recientes .

Tenga en cuenta que hoy en día casi todos los emuladores de terminales gráficos (incluida la masilla) y los multiplexores (pantalla, tmux) admiten 256 colores. Puede obtener indicaciones de colores realmente agradables si usa esta paleta.

Mi recomendación para una solución muy simple es basar el color en el número de la línea tty actual. Por ejemplo, procese la salida del ttycomando para tomar solo el número y derivar el color de eso. Un cierto número de línea tty solo se da a un terminal a la vez, primero debe cerrar ese terminal antes de que el núcleo vuelva a emitir el mismo número de línea. Esto, combinado con 256 colores, garantiza automáticamente que no verá el mismo color dos veces en un momento dado (e incluso con 16 colores daría una distribución bastante uniforme). No es necesario mantener un contador global ni contar terminales o procesos.


1
Hermosa idea con tty. Supongo que nosotros / otros nos hemos concentrado demasiado en esa "pregunta" y olvidamos que podría haber otras soluciones para toda la "necesidad" :) Incluso jugaría con la implementación de un selector de color aleatorio. Si son 256 colores, la selección de colores iguales / similares no debería suceder mucho. Sin embargo, la configuración manual de colores para los números de puntos dados dará una mejor personalización.
GreggD

@TedM. Sí, la pregunta se formuló como una pregunta XY, en la línea de: "Deseo tener un color diferente en cada terminal, así que dime: ¿cómo cuento el número de terminales?"
egmont

@TedM. ¡Aleatorio también es una buena idea! (Una de las propiedades de un mapeo determinista es que después de sudoing el nuevo usuario pueda ajustar fácilmente el mismo color pronta Esto puede o no lo que el autor de la pregunta original desea tener..)
egmont

1
Randomizer es bastante fácil: color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(solo 231 para rechazar la escala de grises), sin embargo, muchos de esos colores resultaron ser solo diferentes tonos y algunos de ellos son oscuros, por lo que podría ser casi invisible y creo que nadie lo usará en la vida real ...
GreggD

No sabemos la versión de Ubuntu del autor de la pregunta. En 16.04 definitivamente ya no hay gnome-pty-helper ( git.gnome.org/browse/vte/commit/?id=299c700 ). No voy a degradar para verificar la jerarquía exacta del proceso en versiones anteriores. Sé que solía haber tal proceso, simplemente no estoy completamente seguro de cómo se veía la jerarquía padre-hijo. Por cierto, tomé la idea del conteo de procesos secundarios de su respuesta original, por lo que no entiendo que "(también por usted)", no importa.
egmont

5

En una situación de usuario único, si tomamos el ejemplo de xterm, simplemente podemos contar el número de pids de xterm; xtermcrea un pid separado para cada ventana.
gnome-terminalSin embargo, ejecuta un solo pid, pero la buena noticia es que crea un proceso hijo para cada ventana y / o pestaña. Podemos recuperar estos procesos secundarios mediante el comando:

pgrep -P <pid_of_gnome-terminal>

Sin embargo, hay algunas complicaciones con las que lidiar:

  • Leyendo su pregunta, podemos suponer que el usuario en este caso es en realidad el propietario de la sesión x . Por lo general, simplemente podemos usar la $USERvariable-, pero esto podría no coincidir con el usuario actualmente conectado $DISPLAY.

  • En una situación multiusuario, los pids que pertenecen a la aplicación de terminal (o cuál) no necesariamente pertenecen a la actual $DISPLAY. Necesitamos separar solo los pids relevantes y los pids secundarios.

  • En Unity (15.10 o inferior), si un segundo usuario inicia sesión, se inicia un proceso adicional ( gnome-pty-helper), que aparece como un proceso secundario gnome-terminal, pero el proceso (obviamente) no tiene una ventana o pestaña. En Mate , el proceso existe de todos modos.

En breve

Para contar el número de pestañas y / o ventanas de una aplicación de terminal, necesitamos:

  • Vea si ejecutamos una aplicación de terminal que tiene múltiples pids o un solo pid en uno $DISPLAY(sesión x)
  • De los procesos en ejecución, separe solo los pids relevantes, ejecutándose en este$DISPLAY
  • Si la aplicación ejecuta procesos secundarios para su pid (para ventanas / pestañas), vea si se gnome-pty-helperejecuta, para corregir el número.

Sin embargo, esto puede ser programado para encontrar de manera confiable el número de ventanas y pestañas abiertas actualmente.

La secuencia de comandos

En el siguiente script, la aplicación de terminal de destino se utiliza como argumento . El script funciona en muchas terminales en las que lo probé. Una excepción es Tildaen este momento.

Un ejemplo

  • Tengo dos usuarios conectados, uno (no el actual) con dos gnome-terminalventanas, uno (el que está en la imagen) con tres gnome-terminalventanas y dos xtermventanas.

ingrese la descripción de la imagen aquí

El comando:

/path/to/get_terms.sh gnome-terminal

salidas:

3

mientras

/path/to/get_terms.sh xterm

salidas:

2

La secuencia de comandos

#!/bin/bash

terminal=$1

# get the user running the current x-session
username=$(who | grep $DISPLAY | head -1 | awk '{print $1}')
# get the pid of the terminal for the current user
userpid=$(pgrep -u $username $terminal)
# check what type the terminal is (multi pid/single pid)
npids="$(echo "$userpid" | wc -w)"
# in case of a single pid, count the children
if [ "$npids" -eq 1 ]; then
  # check if gnome-pty-helper runs (starts when multiple users are logged in)
  ptpid=$(pgrep gnome-pty-helpe)
  # get number of child- procs
  let "orig = $( pgrep -P $(pgrep -u $username $terminal) | wc -w )" 
  # if pty-helper runs, correct the number of child procs
  if [ -n "$ptpid" ] && [ -n "$userpid" ]; then
    let "n_terms = $orig-1"; else let "n_terms = $orig"
  fi
  # if no child procs run, n-terminals = n-counted pids (difference Mate <> Unity)
  if [ "$n_terms" -eq 0 ]; then echo $orig; else echo $n_terms; fi
# in case of multiple pids, count the pids
elif [ "$npids" -gt 1 ]; then echo $npids
fi

Usar

  • Copie el script en un archivo vacío, guárdelo como get_terms.sh, hágalo ejecutable y ejecútelo con el comando:

    /path/to/get_terms.sh <terminal_application>

Aquí siempre tengo uno en gnome-pty-helperejecución, incluso cuando solo hay un usuario conectado (justo después de reiniciar) y cuando abro cualquier cantidad de terminales se ejecuta en segundo lugar, el mismo ayudante. Su nuevo script parece estar funcionando para mate-terminal (no pudo causar esa cosa cero), pero con xterm, cuando solo tengo 1 abierto, se muestra 0y comienza a mostrar un buen número solo después del segundo y con gnome-terminal siempre muestra uno menos (se genera 0cuando solo se abre uno).
GreggD

@TedM. Gracias, esa es información útil, arreglada ahora.
Jacob Vlijm

Realmente admiro tu "pasión" :) ... pero todavía hay un problema con gnome-terminal. Uno da 1, dos da 1, tres da 2, cuatro da 3, etc. Además de mi nuevo descubrimiento, "Tilda" de MATE (ese terminal extra "desconocido" en mi respuesta) también tiene el mismo problema que gnome-terminal, pero con sus pestañas Sin embargo, xterm y mate-terminal parecen estar funcionando bien.
GreggD

@TedM. Gracias por mencionar! Pregunta tonta, pero ¿estás seguro de que usas el último código? En Mate 15.10 todas las pruebas que ejecuto funcionan sin excepción. ¿Cuál es tu versión Mate? En Unity todo ya funcionó bien.
Jacob Vlijm

@TedM. También en mi bastante en blanco 15.10 Mate, está allí por defecto. ¡Solo volví a realizar las pruebas, perfectamente! ¿podría pedirle mañana que ejecute una versión editada de la secuencia de comandos y publique el resultado en alguna parte, para ver qué causa la excepción en su caso?
Jacob Vlijm

1

Una awkforma:

who | awk 'BEGIN{count=0}{ if(NR!=1){count++} }END{print count}'

Explicación:

En el comando 1 liner anterior, awkse utiliza para encontrar el recuento de terminales. Dentro del awkprograma, solo está verificando el número de líneas devueltas por quién ordena: 1.


esto devuelve 0 para mí, lo cual es claramente falso ...
Zanna

Este funciona muy bien para mi mate-terminal y xterm, parece a prueba de balas.
GreggD

De manera concisa: who | awk 'END{print NR - 1}'ya que lo que quieres es número de líneas - 1.
muru

0

Una forma simple también puede ser simplemente ejecutar System Monitor(si se inicia desde la Terminal, debe escribir gnome-system-monitor) y, en la pestaña "Procesos", organice los procesos en ejecución por Nombre y luego cuente el número de ocurrencias Bashen la lista (estarán todos juntos si lo ordena por nombre, por lo que es fácil contar).

Tenga en cuenta que debe buscar Bashy no buscar Gnome Terminalsi desea ver el número de terminales abiertas por usuario. Una vez que abra una Terminal Gnome Terminal, también aparecerá en la lista de Procesos, pero seguirá siendo una, incluso si se abren más Terminales. El botón "Ver" en le System Monitorpermite establecer qué procesos ver, por ejemplo. Todos los procesos / Procesos de usuario / Activo ...


Dado que OP quiere usar el resultado para configurar automáticamente los colores del terminal, esta no parece ser una opción realmente relevante.
Jacob Vlijm

Lo siento, ahora veo que quiere usarlo en el script. Pero entonces sería ps -ef | grep UserName | grep bash | grep -v grep | wc -l no funciona?
NonStandardModel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.