Tengo un código compilado de C++ que puedo ejecutar, llamémoslo run_process .
Para describir run_process , es un código que espera continuamente (bucle infinito/mientras es verdadero) la entrada de texto y hace el preprocesamiento del texto y luego imprime la entrada preprocesada en la salida:
Me gustaría saber si puedo hacer algún comando/solicitud para enviar texto de entrada/STDIN a este proceso en ejecución y obtener el texto de salida, por el momento me gustaría evitar editar run_process y encontrar una solución "externa".
Probé la solución propuesta aquí: https://serverfault.com/a/178470 y ejecuté:
echo "test" > /proc/2657677/fd/0 echo "test\n" > /proc/2657677/fd/0 echo -ne "test\n" > /proc/2657677/fd/0Y obtuve esto:
No obtengo el resultado, es como si no pudiera simular la tecla ENTRAR, o simplemente imprimir el texto junto a "Cadena de entrada" porque cuando presiono la tecla ENTRAR no obtengo nada en el resultado:
Si tiene alguna solución para esto, incluso usando Python o cualquier otro idioma, todas las soluciones serán interesantes.
Para más detalles, el código run_process usa la función readline de c++:
char* input = readline("Input string: ");Línea 90 de esto: https://opengrm.org/doxygen/thrax/html/rewrite-tester-utils_8cc_source.html#l00245 y para obtener más información, puede ver que el código que llamé "run_process" está en realidad en la línea 247.
La biblioteca readline hace mucho más que leer una sola línea de texto. No sé las reglas exactas de lo que hace en qué circunstancias, pero detectará la presencia de una terminal y habilitará cosas como la edición de línea y el historial de línea de comando si así se indica.
Si inicia el programa run_process , sus flujos stdin y stdout generalmente se conectan al terminal que ejecuta el shell que se usa para iniciar el programa. Esto podría ser una terminal real o, más probablemente, en estos días, una pseudo terminal . Tal pseudo terminal tiene un lado maestro, que está controlado por el emulador de terminal que está utilizando (por ejemplo, xterm), y un lado del cliente, que se usa como stdin y stdout del proceso de primer plano que se ejecuta en ese terminal.
Si está escribiendo en el archivo /proc/.../fd/0 , está escribiendo en el lado del cliente del pseudo terminal. Esto pasa por alto toda la funcionalidad del terminal, que normalmente realiza el controlador del pseudo terminal. En cambio, los datos se envían al proceso tal como están escritos.
La biblioteca readline sabe que está conectada a un pseudo terminal y utiliza su funcionalidad para, por ejemplo, detectar pulsaciones de tecla ENTER (esto habilita "líneas" multilínea en readline). La parte esencial aquí es que readline no solo se basa en el flujo de caracteres de entrada para el salto de línea, sino también en las funciones (pseudo) terminales. Esta es la razón por la que escribir directamente en /proc/.../fd/0 (que omite estas funciones) no funciona en combinación con readline .
Ahora creo que tienes varias opciones (puede haber más, pero estas son las que se me ocurrieron):
No use readline , pero lea directamente desde stdin y rompa líneas en caracteres de nueva línea. Sin embargo, perderá todas las características geniales de readline . Si su programa está diseñado para usarse solo con entrada generada, esto podría no ser un problema, pero si el programa también debe presentar una buena entrada interactiva , probablemente no quiera prescindir de readline .
No utilice un pseudo terminal para el flujo de entrada. En su lugar, puede usar, por ejemplo, un archivo especial fifo como este
$ mkfifo myfifo $ tail -f myfifo | ./run_processy enviar datos al proceso con
$ echo "test" > myfifo y finalmente elimine el fifo nuevamente usando rm myfifo . El comando tail -f se usa para mantener el fifo abierto entre diferentes echo .
use una herramienta como socat para crear un pseudo terminal adicional para el cual tiene control en el lado maestro:
$ tty $ socat STDIO,raw,echo=0 SYSTEM:./run_process,pty,stderry escribir al proceso por
$ echo "test" > /dev/pts/<number_returned_by_the_above_tty_command> Con socat también tienes muchas opciones diferentes. Si cambia la fuente STDIO a una opción de conexión diferente de socat , puede hacer fácilmente que el programa run_process , por ejemplo, escuche conexiones tcp o sockets de dominio unix, que también se pueden usar para la transferencia de datos bidireccional.