¿Cómo leer / escribir en el dispositivo tty *?


29

Tengo un dispositivo que envía información por USB a mi computadora. Arch Linux configura este dispositivo mediante la creación de un archivo con el nombre ttyUSB0de /dev/. He estado usando GTKtermpara recibir esta información entrante y mostrarla en una ventana de terminal emulada.

Mi pregunta es, ¿cómo exactamente GTKtermlee / escribe en este ttyUSB0archivo y dónde podría comenzar a aprender cómo implementar una funcionalidad similar? Es decir, en la forma más básica, ¿cómo podría escribir un carácter ttyUSB0o, por el contrario, recibir un byte y escribirlo en un archivo?


1
Intenta usar cat para leer y echo para escribir. "Todo es un archivo" en unix :)
dchirikov

Puede intentar abrir una consola serie en él. screenpuede hacer esto, yminiterm
mikeserv

Estaba pensando en términos de un enfoque programático. Si esto es cierto y es realmente tan fácil (solo abrir y leer el archivo), ¿escribiría un bucle infinito para abrir, leer, cerrar el archivo y actualizar continuamente cuando haya nuevos datos desde la vez anterior? ¿Qué sucede si el dispositivo 'tty' intenta escribir en el archivo si lo tiene abierto en su programa?
sherrellbc

Puede ser útil : cmrr.umn.edu/~strupp/serial.html : open (), read (), write () y select (). Nada especial, parece.
dchirikov

@sherrellbc: puede hacer scripts screeny / o minitermprogramáticamente.
mikeserv

Respuestas:


38

Los TTY son archivos que puede usar como cualquier otro. Puede abrirlos con las herramientas estándar de apertura de archivos de su idioma y leer o escribir desde ellos. Tienen un comportamiento especial que es diferente a los archivos "ordinarios", pero los conceptos básicos son los mismos. Cubriré algunos de los casos especiales al final, pero primero, un experimento.

Una cosa interesante que puede hacer directamente desde una terminal regular. Ejecutar ttye imprimirá una línea como:

/dev/pts/2

Ese es el dispositivo TTY en el que se está ejecutando su terminal. Puede escribir algo en ese terminal:

$ echo Hello > /dev/pts/2
Hello
$

Incluso puedes leerlo:

$ read X < /dev/pts/2
hello
$ echo $X
hello
$

( read Xes el comando "leer una línea desde la entrada estándar a la variable X" de sh; el <es usar / dev / pts / 2 como entrada estándar para el comando de lectura; el primer "hola" que escribí y el segundo se imprimió) .

Si abre otro shell, digamos usando screeno xterm, puede ejecutar ejecutar echo spooky > /dev/pts/2en ese shell para que el texto aparezca en su terminal original, y lo mismo para los otros comandos. Todo esto es solo su shell abriendo un archivo sin saber que es un TTY.


Aquí hay un programa C muy simple que hace exactamente lo que le pediste y escribe un solo carácter en / dev / pts / 3, luego lee un solo byte:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>    
int main() {
    char byte;
    int fd = open("/dev/pts/3", O_RDWR);
    write(fd, "X", 1);
    ssize_t size = read(fd, &byte, 1);
    printf("Read byte %c\n", byte);
    return 0;
}

Un dispositivo TTY real que esté conectado a un shell o emulador de terminal tendrá un comportamiento interesante allí, pero debería recuperar algo.


Para acceder a un terminal necesita tener permiso para usarlo. Esos son solo los permisos de archivo estándar con los que puede ver ls -ly configurar chmod: necesita permiso de lectura para abrir el archivo y leerlo, y permiso de escritura para escribir en él. Los TTY que respaldan su terminal serán de su propiedad, pero el TTY de otro usuario no lo será, y los TTY para dispositivos USB pueden o no serlo, dependiendo de su configuración. Puede cambiar los permisos de la misma manera que siempre.

En cuanto a escribir un programa para trabajar con él, no necesitas hacer mucho especial. Puede ver en el ejemplo que una cosa que no necesita hacer es cerrar el archivo cada vez para que sus datos sean leídos por el otro extremo: los archivos TTY actúan como tuberías, simplemente empujando los datos en ambas direcciones a medida que entran. Cuando escribí un mensaje de texto al TTY, apareció de inmediato, y cuando leí después ya no había nada esperándome. Es no como escribir a un archivo normal, donde los datos se guardan en el disco - que se pasa inmediatamente al otro lado, o se almacena en la memoria hasta que alguien lo lee.

Es posible que desee utilizar la función de selección para que pueda hacer otras cosas mientras espera que el dispositivo diga algo, pero si está contento de esperar a que lleguen los datos, puede usar lecturas de bloqueo y dejar que el sistema operativo haga El levantamiento.

Una cosa a tener en cuenta es que puede haber un tamaño de búfer limitado en el núcleo, y si escribe muchos datos a la vez, puede terminar bloqueando sin querer. Si es probable que sea un problema, use IO sin bloqueo con open("/dev/...", O_RDWR | O_NONBLOCK). El principio será el mismo de cualquier manera.


Estoy intentando sudo echo Hello > /dev/tty4cuando estoy en el entorno de escritorio, pero bash: /dev/tty4: Permission deniedaparece si no estoy conectado a tty4. Sin embargo, si estoy conectado a tty4, todo funciona bien. ¿Cuál es la razón para esto?
Utku

@Utku, ese es sin duda algún tipo de problema de permisos que se eliminan después de la autenticación con el terminal virtual. Compruebe los permisos de archivo antes y después de haber iniciado sesión.ls -l /dev/tty4
sherrellbc

1
la > /dev/tty4parte no es parte del echosubproceso iniciado por, sudosino parte del sudoproceso en sí, que es ejecutado por el usuario actual. se aplican permisos de archivo para el usuario actual en lugar de root.
Robin479
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.