Intenté usar canalizaciones y redirecciones para que la salida (programa C o scripts) termine en el búfer de entrada, como lo printf "\033[6n"
hace, pero no hubo resultados positivos.
¿Alguien sabe cómo esto es posible como:
- una línea de comando
- en un script de shell
- código C
La salida de tuberías _cmd_ > /dev/stdin
y el código C fprintf(stdin, "blah\n");
no tienen ningún efecto mensurable.
Nota:No quiero "canalizar" la entrada a otro comando, quiero "inyectar" caracteres en el "búfer del teclado" (por así decirlo).
EDITAR:El caso de uso original era una aplicación CLI de espacio aislado que permite shell
o system
externocomandospara interactuar con el sistema operativo (por ejemplo, Bas), pero nonomanejar descriptores de archivos.
Respuesta1
Editar:La respuesta cortaera /dev/uinput
, ahora es TIOCSTI
(ver final de la publicación)
Esta es la respuesta hasta ahora, y para abordar los comentarios:
ioctl_tty(2)
No lo tengo, pero una búsqueda TIOCSTI
en la fuente del kernel (a través deElectrones libres) mostrará tiocsti
un "carácter de entrada falso", que utiliza un tty_struct
contexto.
La aplicación en cuestión se ejecuta todo el tiempo, de forma interactiva, por lo que no se pueden utilizar canalizaciones ni redirecciones. Puede shell
realizar secuencias de comandos, sin embargo, a diferencia de muchas otras aplicaciones similares, no captura ni permite capturar los resultados, solo permite stdin
y stdout
hacer lo suyo normalmente.
En el futuro previsible no hay posibilidad de cambiar esto, no es mi aplicación. Sin embargo, pude cortar los resultados de "\033[6n"
, que el kernel inyectó en el búfer del teclado a través de tty_insert_flip_char
& tty_schedule_flip
in src/drivers/tty/tty_buffer.c
, que usa un tty_port
contexto.
Si la memoria no me falla, antes de que se cambiara la estructura del archivo FD, cuando habíasolo4 descriptores de archivos, es posible que haya sido posible lograrlo. Hoy en día, aunque puedes escribir en /dev/stdin
o /proc/self/fd/0
, están conectados /dev/tty#
y todo lo que se escriba en un dispositivo TTY terminará en la pantalla ( /dev/stdout
). El kernel parece omitir la ruta del descriptor de archivos cuando usa TTY, observe que las flip
funciones se refieren a él como unpuerto.
Ninguna aplicación del espacio de usuario tiene acceso a ninguna de esas funciones del kernel. En X-Windows es posible usar xvkbd
and xdotool
or xte
, pero esta aplicación se usa en la consola Linux (VT).
La respuesta (casi) real:
Aunque /dev/uinput
no tiene privilegios de usuario (en la mayoría de los sistemas), sudo
un script printf
funcionará con todos los argumentos.
Alternativamente, el tecladoeventoTambién funcionará, ya que todos los usuarios tienen acceso a él, pero cambia según el inicio y el sistema (el mío normalmente es /dev/input/event0
, pero no siempre).
Después de más investigaciones, ninguno de estos enfoques es práctico, especialmente para secuencias de comandos. Lo que debemos entender acerca de lo que hay que hacer es que sólo queremos presentartextoen el búfer de entrada, no "simular una pulsación de tecla" (que es como funcionan los dispositivos anteriores).
La respuesta real (más práctica):
Una pregunta externa se remitió a una respuesta en stackexchange, de 2011 (aquí). Usa TIOCSTI
. Después de revisar el ejemplo de Perl nuevamente, también puede resultar práctico para secuencias de comandos, donde no se proporciona una aplicación.
perl -le 'require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV
' `_cmds_`
Sin embargo, también se refleja en la pantalla. Después de muchas horas de investigación y experimentación, lo siguiente resulta práctico en un script o en la línea de comando:
stty -echo; perl -le 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV ' `_cmds_` ;stty echo
Nota:aunque TIOCSTI
fue revocado enOpenBSD 6.2(octubre de 2017), aparentemente los desarrolladores del kernel de Linux son del tipoopuestomente, negándose categóricamente a revocarlo (puedes leer más sobre esto en elRevista OpenBSD).
Respuesta2
A partir de Debian Bullseye, console-tools
fue absorbido por kbd
el cual writevt
eranoincluido. Si lo desea, las fuentes están vinculadas en la actualización al final de esta publicación.
writevt /dev/tty# text
, al menos en Linux, tal vez BSD y Unix, actualmente forma parte del console-tools
paquete. El usuario debe tenerescribirprivilegios para el VT. Específicamente, (EDITAR: si está disponible en su sistema operativo) la respuesta completa y correcta al OP es:
writevt `tty` "`_cmds_`"
Esta pregunta muestra la falta de conocimiento profundo sobre los sistemas operativos base por parte de la comunidad StackExchange en su conjunto. writevt
es muy antiguo, es un comando base instalado en el 99% de los sistemas (EDITAR: Debian Linux). Hasta junio de 2002 no había ninguna página de manual ni mantenedor en Debian, lo que puede explicar por qué mucha gente no lo sabe, aunque eso fue hace 15 años. Sin embargo, incluso en Kali Linux (que tienetodo) la mayoría de las veces no figura en la listadisponible comandos, aunque ha estado ahí desde el principio.
A partir de Debian Buster writevt
ya no se instala de forma predeterminada y, según algunos, es posible que ya no exista en ningún paquete (¿debido a la falta de mantenedor? ¿O a un cambio en console-tools
el paquete?)
ACTUALIZACIÓN: de hecho, ya no puedo encontrar console-tools
en la búsqueda de paquetes de Debian (donde verifiqué el contenido originalmente), ni siquiera los backports.
El proyecto del paquete original está aquí:
No se requieren parches. Raspbian/RPiOS tiene una compilación de Debian (Wheezy to Buster) aquí:
http://raspbian.raspberrypi.org/raspbian/pool/main/c/console-tools/
Cita de Yan Dirson:
Proyectos de software (públicos) actuales en los que trabajo El proyecto Debian GNU/Linux, del cual soy miembro desde 1997.
http://ydirson.free.fr/en/software/
El console-tools
paquete del proyecto "Linux Console Tools" todavía está disponible en RPiOS. No es lo mismo que linuxconsoletools
el paquete del proyecto "Linux Console Project", que también está en SourceForge.