La especificación POSIX realmente cubre sus apuestas en lo que respecta al Terminal de Control , y que define así:
- Terminal de control
- La cuestión de cuál de los posibles archivos especiales que se refieren al terminal no se aborda en POSIX.1. El nombre de ruta
/dev/tty
es sinónimo del terminal de control asociado con un proceso.
Eso está en la lista de Definiciones, y eso es todo lo que hay. Pero en General Terminal Interface , se dice algo más:
Un terminal puede pertenecer a un proceso como su terminal de control. Cada proceso de una sesión que tiene un terminal de control tiene el mismo terminal de control. Un terminal puede ser el terminal de control para, como máximo, una sesión. El líder de sesión asigna el terminal de control para una sesión de una manera definida por la implementación. Si un líder de sesión no tiene terminal de control y abre un archivo de dispositivo de terminal que no está asociado con una sesión sin usar la opción O_NOCTTY (ver open ()), se define la implementación si el terminal se convierte en el terminal de control de la sesión líder.
El terminal de control es heredado por un proceso hijo durante una llamada a la función fork (). Un proceso renuncia a su terminal de control cuando crea una nueva sesión con elsetsid()
función; otros procesos restantes en la sesión anterior que tenía este terminal como su terminal de control continúan teniendo. Al cerrar el último descriptor de archivo en el sistema (esté o no en la sesión actual) asociado con el terminal de control, no se especifica si todos los procesos que tenían ese terminal como terminal de control dejan de tener algún terminal de control. No se especifica si y cómo un líder de sesión puede volver a adquirir un terminal de control después de que el terminal de control haya sido cedido de esta manera. Un proceso no renuncia a su terminal de control simplemente cerrando todos sus descriptores de archivos asociados con el terminal de control si otros procesos continúan abriéndolo.
Quedan muchas cosas sin especificar , y sinceramente, creo que tiene sentido. Si bien el terminal es una interfaz de usuario clave, en algunos casos también es todo tipo de otras cosas, como hardware real o incluso una especie de impresora, pero en muchos casos prácticamente no es nada, como xterm
un emulador . Es difícil ser específico allí, y no creo que sea de gran interés para Unix de todos modos, porque los terminales hacen mucho más que Unix.
De todos modos, POSIX también es bastante dudoso sobre cómo ps
debe comportarse en lo que respecta a la comunidad.
Ahí está el -a
interruptor:
- Escriba información para todos los procesos asociados con terminales. Las implementaciones pueden omitir los líderes de sesión de esta lista.
Excelente. Los líderes de sesión pueden ser omitidos. Eso no es muy útil.
Y -t
:
- Escriba información para los procesos asociados con los terminales que figuran en la lista de términos. La aplicación se asegurará de que la lista de términos sea un argumento único en forma de una
<blank>
lista separada por comas. Los identificadores de terminal se darán en un formato definido por la implementación .
... que es otra decepción. Pero continúa diciendo esto sobre los sistemas XSI:
- En los sistemas compatibles con XSI, se darán en una de dos formas: el nombre de archivo del dispositivo (por ejemplo,
tty04
) o, si el nombre de archivo del dispositivo comienza con tty
, solo el identificador que sigue a los caracteres tty
(por ejemplo 04
) .
Eso es un poco mejor, pero no es un camino. También en los sistemas XSI existe el -d
interruptor:
- Escriba información para todos los procesos, excepto los líderes de sesión.
... que al menos está claro. Puede especificar el -o
modificador de rendimiento también con la tty
cadena de formato, pero, como ha notado, su formato de salida está definido por la implementación. Aún así, creo que es tan bueno como se pone. Creo que, con mucho trabajo, los interruptores anteriores en combinación con algunas otras utilidades pueden darle un buen estadio. Sin embargo, para ser sincero, no sé cuándo / cómo se rompe para usted, y no he podido imaginar una situación en la que lo haría. Pero, creo que probablemente si agregamos fuser
y find
podemos verificar la ruta.
exec 2<>/dev/null
ctty=$(sh -c 'ps -p "$$" -o tty=' <&2)
sid=$(sh -c 'ps -Ao pid= -o tty=|
grep '"$ctty$"' |
grep -Fv "$(ps -do pid=)"' <&2)
find / -type c -name "*${ctty##*/}*" \
-exec fuser -uv {} \; 2>&1 |
grep ".*$ctty.*${sid%%"$ctty"*}"
El /dev/null
material era solo para mostrar que podía funcionar cuando ninguna de las subcapas de búsqueda tenía ninguna conexión de 0,1,2 conectada a la comunidad. De todos modos, eso imprime:
/dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh
Ahora lo anterior obtiene el camino completo en mi máquina, e imagino que lo haría para la mayoría de las personas en la mayoría de los casos. También me imagino que podría fallar. Es solo una heurística aproximada.
Probablemente, esto podría fallar por muchas otras razones, pero si está en un sistema que permite que el líder de la sesión renuncie a todos los descriptores y, sin embargo, siga siendo el sid, según lo permitan las especificaciones, entonces esto definitivamente no va a ayudar. Dicho esto, creo que esto puede obtener una estimación bastante buena en la mayoría de los casos.
Por supuesto, el más fácil de lo que debe hacer si tiene algún descriptores conectados a su CTTY es sólo ...
tty <&2
...o similar.
ps
solución cubre la mayoría de los sistemas (ywho
no ayuda más queps
), posiblemente con un poco más de código para manejar solo el identificador (como "04"). Me preguntaba si habría una solución aún más portátil.