¿Cómo "cruzar" stdin
y stdout
de dos programas? Específicamente, tengo 2 programas llamados pgm1
y pgm2
, son juegos interactivos de tres en raya. Ambos generan un número (0to8) que indica la posición donde quiere marcar y esperan otro número (0to8) que indica dónde quiere marcar el usuario. La diferencia entre los dos es pgm1
que hace el primer movimiento y pgm2
hace el segundo movimiento. Ambos funcionan bien a través de un usuario interactivo. ¿Se puede hacer que jueguen entre sí mediante la redirección io?
Intenté las siguientes cosas en vano:
- Ábralo
pgm2
en una terminal separada (espera entrada), busque su pid. Luego ejecutapgm1
en otra terminal./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
- Hice 2 tuberías usando mkfifo, digamos
pipe1
ypipe2
ejecuté lo siguiente en dos terminales diferentes:./pgm1 < pipe1 > pipe2
y./pgm2 < pipe2 > pipe1
- Probé los dos anteriores, ejecutando pgm1 antes de pgm2, ejecutando pgm2 antes de pgm1.
Me aseguré de usarlofflush(stdout)
en ambos programas, inmediatamente después de usarprintf()
.
¿Alguien podría decirme qué me falta o qué me sale mal o es posible?
Respuesta1
Debería poder hacer que esto funcione con un FIFO y una tubería.
$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo
La entrada del programa dos es el quince y las salidas a la tubería. La entrada del programa uno es la tubería y las salidas al FIFO.
Sin embargo, tenga cuidado: esto es muy picante en general y puede bloquearse si el "ping/pong" entre los procesos no es perfecto.
Vea también esta pregunta de Stack Overflow:¿Cómo redirigir la salida estándar del segundo proceso a la entrada estándar del primer proceso?
Respuesta2
Tienes un punto muerto en tu: ./pgm1 < pipe1 > pipe2
y./pgm2 < pipe2 > pipe1
Lo open("pipe1", O_RDONLY)
realizado por el shell antes de la ejecución pgm1
se bloqueará hasta que algo más escriba open
en esa misma tubería. Hasta que no se haga, no funcionará el siguiente open("pipe2", O_WRONLY)
.
Lo mismo para el otro. Se open("pipe2", O_RDONLY)
bloqueará y debido a que open("pipe2", O_WRONLY)
no se realizará porque el otro shell está esperando un escritor pipe1
, tienes un punto muerto.
¿Lo habías escrito?
pgm1 < pipe1 > pipe2 & pgm2 > pipe1 < pipe2
Habría funcionado.
En Linux, también puedes escribirlo:
{ pgm1 <&3 3<&- | pgm2 3<&-; } 3< /dev/fd/1 | :