Si las tuberías en su sistema son bidireccionales (como lo son en Solaris 11 y algunos BSD al menos, pero no Linux):
cmd1 <&1 | cmd2 >&0
Pero cuidado con los callejones sin salida.
También tenga en cuenta que algunas versiones de ksh93 en algunos sistemas implementan tuberías ( |
) utilizando un par de sockets . los pares de zócalos son bidireccionales, pero ksh93 cierra explícitamente la dirección inversa, por lo que el comando anterior no funcionaría con esos ksh93s incluso en sistemas donde las tuberías (como las crea la pipe(2)
llamada al sistema) son bidireccionales.
Bueno, es bastante "fácil" con tuberías con nombre (
mkfifo
). Pongo comillas fáciles porque a menos que los programas estén diseñados para esto, es probable un punto muerto.Ahora, normalmente hay buffering involucrado en escribir stdout. Entonces, por ejemplo, si ambos programas fueran:
esperarías un bucle infinito. Pero en cambio, ambos se estancarían; necesitaría agregar
$| = 1
(o equivalente) para desactivar el almacenamiento en búfer de salida. El punto muerto se debe a que ambos programas están esperando algo en stdin, pero no lo ven porque está en el búfer stdout del otro programa y aún no se ha escrito en la tubería.Actualización : incorporando sugerencias de Stéphane Charzelas y Joost:
hace lo mismo, es más corto y más portátil.
fuente
prog1 < fifo | prog2 > fifo
.prog1 < fifo | tee /dev/stderr | prog2 | tee /dev/stderr > fifo
.prog2 < fifo0 > fifo1
, puedes evitar tu pequeño baile conexec 30< ...
(que por cierto solo funciona conbash
oyash
para mayores de 10 años así).dash
parece estar bien también (pero se comporta un poco diferente)No estoy seguro de si esto es lo que estás tratando de hacer:
Esto comienza con la apertura de un socket de escucha en el puerto 8096, y una vez que se establece una conexión, genera el programa
second
con sustdin
medida que la corriente de salida ystdout
como entrada de corriente.Luego,
nc
se inicia un segundo que se conecta al puerto de escucha y genera el programafirst
con sustdout
entrada de flujo y sustdin
salida de flujo.Esto no se hace exactamente usando una tubería, pero parece hacer lo que necesita.
Como esto usa la red, esto se puede hacer en 2 computadoras remotas. Esta es casi la forma en que funcionan un servidor web (
second
) y un navegador web (first
).fuente
nc -U
para los sockets de dominio UNIX que solo ocupan espacio de direcciones del sistema de archivos.Puedes usar pipexec :
fuente
bash
la versión 4 tiene uncoproc
comando que permite que esto se haga en purobash
sin canalizaciones con nombre:Algunas otras conchas también pueden funcionar
coproc
también.A continuación se muestra una respuesta más detallada, pero encadena tres comandos, en lugar de dos, lo que hace que sea un poco más interesante.
Si está contento de usar también
cat
ystdbuf
luego construir, puede ser más fácil de entender.Versión
bash
concat
ystdbuf
fácil de entender:Tenga en cuenta que debe usar eval porque la expansión variable en <& $ var es ilegal en mi versión de bash 4.2.25.
Versión usando pure
bash
: divídase en dos partes, inicie la primera tubería bajo coproc, luego almuerce la segunda parte, (ya sea un solo comando o una tubería) volviendo a conectarla a la primera:Prueba de concepto:
archivo
./prog
, solo un programa ficticio para consumir, etiquetar y volver a imprimir líneas. Usar subconjuntos para evitar problemas de almacenamiento en búfer puede ser excesivo, no es el punto aquí.file
./start_cat
Esta es una versión que usabash
,cat
ystdbuf
o archivo
./start_part
. Esta es una versión que usa purobash
solamente. Para fines de demostración, todavía estoy usandostdbuf
porque su programa real tendría que lidiar con el almacenamiento interno de todos modos para evitar el bloqueo debido al almacenamiento en búfer.Salida:
Eso lo hace.
fuente
Un bloque de construcción conveniente para escribir tales tuberías bidireccionales es algo que conecta el stdout y el stdin del proceso actual. Llamémoslo ioloop. Después de llamar a esta función, solo necesita iniciar una tubería normal:
Si no desea modificar los descriptores del shell de nivel superior, ejecute esto en un subshell:
Aquí hay una implementación portátil de ioloop usando una tubería con nombre:
La canalización con nombre existe en el sistema de archivos solo brevemente durante la configuración de ioloop. Esta función no es POSIX porque mktemp está en desuso (y es potencialmente vulnerable a un ataque racial).
Es posible una implementación específica de Linux usando / proc / que no requiera una tubería con nombre, pero creo que esta es más que suficiente.
fuente
( : <$FIFO & )
con más detalle. Gracias por tu publicación.mktemp
? Lo uso ampliamente, y si una herramienta más nueva ha ocupado su lugar, me gustaría comenzar a usarla.También hay
dpipe
, la "tubería bidireccional", incluida en el paquete vde2 e incluida en los sistemas actuales de administración de paquetes de distribución .dpipe processA = processB
socat , la herramienta de conectar todo a todo.
socat EXEC:Program1 EXEC:Program2
Como @ StéphaneChazelas señala correctamente en los comentarios, los ejemplos anteriores son la "forma base", tiene buenos ejemplos con opciones en su respuesta para una pregunta similar .
fuente
socat
usa enchufes en lugar de tuberías (puede cambiar eso concommtype=pipes
). Es posible que desee agregar lanofork
opción para evitar un proceso adicional de socat que inserte datos entre las tuberías / tomas. (gracias por la edición en mi respuesta por cierto)Hay muchas respuestas geniales aquí. Así que solo quiero agregar algo para jugar fácilmente con ellos. Supongo
stderr
que no se redirige a ninguna parte. Cree dos scripts (digamos a.sh y b.sh):Luego, cuando los conecte de cualquier manera que debería ver en la consola:
fuente