Emuladores de terminal
El lado maestro reemplaza la línea (el par de cables TX / RX) que va al terminal.
El terminal muestra los caracteres que recibe en uno de los cables (algunos de ellos son caracteres de control y hacen que haga cosas como mover el cursor, cambiar el color ...) y envía en otro cable los caracteres correspondientes a las teclas que escribe.
Los emuladores de terminal como xterm no son diferentes, excepto que en lugar de enviar y recibir caracteres en los cables, leen y escriben caracteres en su descriptor de archivo en el lado maestro. Una vez que han generado la terminal esclava, y comenzaron su shell en eso, ya no tocan eso. Además de emular el par de cables, xterm también puede cambiar algunas de las propiedades de disciplina de línea a través del descriptor de archivo al lado maestro. Por ejemplo, pueden actualizar los atributos de tamaño para que se envíe un SIGWINCH a las aplicaciones que interactúan con el esclavo pty para notificarles sobre un tamaño cambiado.
Aparte de eso, hay poca inteligencia en el emulador de terminal / terminal.
Lo que escribe en un dispositivo terminal (como el pty slave) es lo que quiere decir que se mostrará allí, lo que lee de él es lo que ha escrito allí, por lo que no tiene sentido que el emulador de terminal lea o escriba en eso . Ellos son los del otro extremo.
La disciplina de la línea tty
Mucha de la inteligencia está en la disciplina de la línea tty . La disciplina de línea es un módulo de software (que reside en el controlador, en el núcleo) empujado encima de un dispositivo serial / pty que se encuentra entre ese dispositivo y la línea / cable (el lado maestro para un pty).
Una línea en serie puede tener un terminal en el otro extremo, pero también un mouse u otra computadora para la conexión en red. Puede adjuntar una disciplina de línea SLIP, por ejemplo, para obtener una interfaz de red en la parte superior de un dispositivo serie (o dispositivo pty), o puede tener una disciplina de línea tty . La disciplina de línea tty es la disciplina de línea predeterminada al menos en Linux para dispositivos seriales y pty. En Linux, puede cambiar la disciplina de línea con ldattach
.
Puede ver el efecto de deshabilitar la disciplina de línea tty emitiendo stty raw -echo
(tenga en cuenta que el indicador bash u otras aplicaciones interactivas como vi
configurar el terminal en el modo exacto que necesitan, por lo que desea utilizar una aplicación tonta como cat
para experimentar con eso). Luego, todo lo que se escribe en el dispositivo terminal esclavo llega inmediatamente al lado maestro para que xterm lo lea, y cada carácter escrito por xterm en el lado maestro está inmediatamente disponible para leer desde el dispositivo esclavo.
La disciplina de línea es donde se implementa el editor de línea interno del dispositivo terminal . Por ejemplo, con stty icanon echo
(como es el valor predeterminado), cuando escribe a
, xterm escribe a
en el maestro, luego la disciplina de línea lo repite (lo pone a a
disposición para leerlo xterm
para mostrarlo), pero no pone a disposición nada para leer en el lado esclavo . Luego, si escribe retroceso, xterm envía un carácter ^?
o ^H
, la disciplina de línea (como eso ^?
o ^H
corresponde a la erase
configuración de disciplina de línea) vuelve a enviar al maestro a ^H
, space
y ^H
para xterm
borrar ela
acaba de escribir en su pantalla y todavía no envía nada a la aplicación que lee desde el lado esclavo, solo actualiza su búfer interno del editor de línea para eliminar lo que a
ha escrito anteriormente.
Luego, cuando presiona Enter, xterm envía ^M
(CR), que la disciplina de línea convierte en entrada a a ^ J (LF), y envía lo que ha ingresado hasta ahora para leer en el lado esclavo (una aplicación de lectura /dev/pts/x
recibirá lo que ha escrito incluyendo LF, pero no a
desde que lo ha eliminado), mientras que en el lado maestro, envía un CR y LF para mover el cursor a la siguiente línea y al inicio de la pantalla.
La disciplina de línea también es responsable de enviar la SIGINT
señal al grupo de procesos en primer plano del terminal cuando recibe un ^C
carácter en el lado maestro, etc.
Muchas aplicaciones de terminal interactivas deshabilitan la mayoría de las características de esa disciplina de línea para implementarlas ellos mismos. Pero en cualquier caso, tenga en cuenta que el terminal ( xterm
) tiene poca participación en eso (excepto mostrar lo que se le dice que muestre).
Y solo puede haber una sesión por proceso y por dispositivo terminal. Una sesión puede tener un terminal de control conectado pero no tiene que hacerlo (todas las sesiones comienzan sin un terminal hasta que abren uno). xterm
, en el proceso en el que se bifurca para ejecutar su shell, generalmente creará una nueva sesión (y, por lo tanto, se desconectará del terminal desde el que lo inició xterm
), abra el nuevo /dev/pts/x
que ha generado, al conectar ese dispositivo terminal a la nueva sesión. Luego ejecutará su shell en ese proceso, por lo que su shell se convertirá en el líder de la sesión. Su shell o cualquier shell interactivo en esa sesión generalmente hará malabarismos con los grupos de procesos y tcsetpgrp()
, para establecer los trabajos en primer plano y en segundo plano para ese terminal.
En cuanto a qué información almacena un dispositivo terminal con una disciplina tty (serial o pty) , eso es lo que el stty
comando muestra y modifica. Toda la configuración de disciplina: tamaño de la pantalla del terminal, local, indicadores de salida de entrada, configuraciones para caracteres especiales (como ^ C, ^ Z ...), velocidad de entrada y salida (no relevante para ptys). Eso corresponde a las funciones tcgetattr()
/ tcsetattr()
que en Linux se asignan a TCGETS
/ TCSETS
ioctls, y TIOCGWINSZ
/ TIOCSWINSZ
para el tamaño de la pantalla. Puede argumentar que el grupo de proceso en primer plano actual es otra información almacenada en el dispositivo terminal ( tcsetpgrp()
/ tcgetpgrp()
, TIOC{G,S}PGRP
ioctls), o el búfer de entrada o salida actual.
Tenga en cuenta que la información del tamaño de la pantalla almacenada en el dispositivo terminal puede no reflejar la realidad. El emulador de terminal generalmente lo configurará (a través del mismo ioctl en el tamaño maestro) cuando se cambie el tamaño de su ventana, pero puede salir de la sincronización si una aplicación llama al ioctl en el lado esclavo o cuando el cambio de tamaño no se transmite (en caso de una conexión ssh que implica otra pty generada por sshd
si ssh
ignora el SIGWINCH
por ejemplo). Algunos terminales también pueden consultar su tamaño a través de secuencias de escape, por lo que una aplicación puede consultarlo de esa manera y actualizar la disciplina de línea con esa información.
Para más detalles, se puede echar un vistazo a la termios
y tty_ioctl
páginas de manual en Debian, por ejemplo.
Para jugar con otras disciplinas de línea:
Emule un mouse con un pseudo-terminal:
socat pty,link=mouse fifo:fifo
sudo inputattach -msc mouse # sets the MOUSE line discipline and specifies protocol
xinput list # see the new mouse there
exec 3<> fifo
printf '\207\12\0' >&3 # moves the cursor 10 pixels to the right
Arriba, el lado maestro de la pty es terminado por socat en una tubería con nombre ( fifo
). Conectamos ese fifo a un proceso (el shell) que escribe 0x87 0x0a 0x00 que en el protocolo del sistema del mouse significa no button pressed, delta(x,y) = (10,0)
. Aquí, nosotros (el shell) no estamos emulando un terminal, sino un mouse, los 3 bytes que enviamos no deben ser leídos (potencialmente transformados) por una aplicación desde el dispositivo terminal ( mouse
arriba del cual hay un enlace simbólico hecho por socat
algún /dev/pts/x
dispositivo) , pero deben interpretarse como un evento de entrada del mouse.
Crear una interfaz SLIP:
# on hostA
socat tcp-listen:12345,reuseaddr pty,link=interface
# after connection from hostB:
sudo ldattach SLIP interface
ifconfig -a # see the new interface there
sudo ifconfig sl0 192.168.123.1/24
# on hostB
socat -v -x pty,link=interface tcp:hostA:12345
sudo ldattach SLIP interface
sudo ifconfig sl0 192.168.123.2/24
ping 192.168.123.1 # see the packets on socat output
Arriba, el cable serie se emula socat
como un socket TCP entre hostA y hostB. La disciplina de línea SLIP interpreta los bytes intercambiados a través de esa línea virtual como paquetes IP encapsulados SLIP para su entrega en la sl0
interfaz.
cat /dev/ptmx &
que abre una nueva pty, pero no hay ningún proceso que pueda encontrar asociado con él, entonces, ¿cómo lo usarías? Lo intenté en segundo lugarecho "1" >/dev/ptmx
, pero eso no hizo nada ... ¿Por qué estoy interesado en esto? Pd a menudo cuando uno se conecta de forma remota a través dessh
(por ejemplo), se obtienePTY allocation request failed
oNo controlling tty: open /dev/tty
de error, lo que impide el control de trabajos. Sería bueno entenderlos mejor.pty
página de manual para más detalles.physical term
----tty
----bash
en terminales ypty(m)
----tty
----pty(s)
----bash
en emuladores de terminales? ¿Fue latty
disciplina responsable de hacer eco de los caracteres en la terminal física también? 2. ¿Es el programa emulador de terminal el que se conecta al teclado / pantalla para administrar la entrada? 3. De acuerdo con lo que entendí, usted dijo que el almacenamiento en línea de los comandos bash / toda la entrada del terminal se realiza mediantetty
disciplina de línea en lugar de los almacenamientos intermedios de E / S de las funciones de CI / O. ¿Es esto correcto?Editar: desde esta respuesta, escribí un artículo dedicado en mi blog, para las personas que estarían interesadas en obtener más detalles.
Después de mucha lectura, esto es lo que entendí.
/dev/ptmx
no asigna la parte esclava : asigna la "parte maestra pseudo terminal". / dev / ptmx no es el pseudo terminal maestro : es un multiplexor maestro pseudo terminal . Se ha creado con el estándar Unix98 PTY para evitar condiciones de carrera al asignar un pseudo terminal maestro ( fuente ).La parte maestra (ptm) del pseudo terminal no está representada en el sistema de archivos. Está representado por un descriptor de archivo.
La parte esclava (pts) está representada por un archivo en
/dev/pts/N
dondeN
hay un número.Los pts se obtiene de la PTM a través de la llamada sucesiva de
grandpt
,unlockpt
,ptsname
. ( Fuente )El ptm reemplaza el controlador AUR dedicado a comunicarse con el dispositivo y la edición de línea. Por lo tanto, no emula de ninguna manera un terminal, sino que proporciona la función de edición de línea y proporciona una forma de visualizar y comunicarse con pts. ( Fuente )
Aquí hay un gráfico de lo que era un TTY conectado a un dispositivo de hardware
Y aquí hay un gráfico de un tty conectado a un ptm
El archivo ptm maneja diferentes argumentos Ioctl (ISPTM, UNLKPT, TIOCREMOTE, TIOCSIGNAL) que los pts.
Los procesos interactúan con los dispositivos a través de acciones realizadas en un archivo virtual (lectura, escritura, ioctl ..). El archivo en sí no existe y el controlador lo utiliza para activar acciones cuando se llama a los métodos de lectura o escritura. (Ver Anexo para información sobre conductores)
Un TTY define una forma precisa de interactuar con él. Los procesos escriben y leen desde el dispositivo y esperan el mismo comportamiento independientemente de qué tipo de TTY se implemente.
Los pts se comportan como un controlador TTY. Su método de lectura y escritura se utiliza para implementar el comportamiento del controlador TTY. Como no hay un dispositivo real para enviar los datos, se crea un par de secuencias y el ptm implementa una función de lectura para leer los datos que envían los pts a la secuencia, y una función de escritura para enviar datos a la secuencia que estará disponible cuando los pts lo leerán.
Recuerde, el archivo que representa un dispositivo no es un archivo clásico, y si
xterm
quiere ver lo que se ha escrito en el archivo, no puede simplemente abrirlo y leerlo, ya que estas funciones tienen un comportamiento completamente diferente aquí.No lo creo, el ID de sesión se define por el primer proceso que adjunta los pts (bash en general), y no veo una manera de crear otra sesión y adjuntarla a los mismos pts. Tal vez una herramienta como
socat
podría hacer esto?Los pts almacenan 2 categorías de información sobre el terminal con el que se está comunicando: el
Terminfo
y elTermcap
. Por lo general, muchos emuladores de terminal se basan en una biblioteca que administra la información de captación de términos para ellos (que proporcionará todos los valores de capacidades para emular un VTX100, por ejemplo). Un ejemplo de dicha biblioteca es libvte . Editar (consulte el comentario de Stephane Chazelas): los pts no almacenan las capacidades del terminal.Anexo
fuente
Aquí hay un esquema que hice hace algún tiempo sobre cómo
sshd
funciona. No se refiere al funcionamiento de la disciplina de línea y otras cosas, pero agrega una ilustración de la vida real de quién interactúa con qué:fuente
-T
, que el hombre dice que desactiva la asignación de pseudo terminales. por ejemplo:ssh -T emasculateur@localhost "sleep 10"
luegops aux|grep sleep
muestra esto:emasculateur 21826 0.0 0.0 23032 3728 ? Ss 02:49 0:00 zsh -c sleep 10
en ese caso, ¿dónde escribe bashstdout
ystderr
? Espero que mi pregunta tenga sentido./dev/null
gustar para un demonio normal, pero no estoy seguro. Ver también: serverfault.com/questions/593399/…nohup
oscreen
/tmux
.man pts
dice:Acerca de
/dev/pts/X indexing
:cada X es una sesión que se abre, por lo que los esclavos necesitan indexar.
Acerca de
TeteType (/dev/ttyN
):Su consola real ha sido generada por su sistema de arranque como
sysV
.Acerca de por qué esclavo insted de maestro: http://commons.wikimedia.org/wiki/File:Termios-script-diagram.png
fuente