¿Cómo funciona la tubería? Si ejecuto un programa a través de CLI y redirijo la salida a un archivo, ¿podré canalizar ese archivo a otro programa mientras se escribe?
Básicamente, cuando se escribe una línea en el archivo, me gustaría que se canalice inmediatamente a mi segunda aplicación (estoy tratando de dibujar dinámicamente un gráfico a partir de un programa existente). Simplemente no estoy seguro si la tubería completa el primer comando antes de pasar al siguiente comando.
¡Cualquier retroalimentación sería muy apreciada!

adam rosenfield
Si desea redirigir la salida de un programa a la entrada de otro, simplemente use una canalización simple:
program1 arg arg | program2 arg arg
Si desea guardar la salida de program1
en un archivo y canalizarlo en program2
puedes usar tee(1)
:
program1 arg arg | tee output-file | program2 arg arg
Todos los programas en una canalización se ejecutan simultáneamente. La mayoría de los programas suelen utilizar bloqueando E/S: si cuando intentan leer su entrada y no hay nada allí, cuadra: es decir, se detienen y el sistema operativo los desprograma para que se ejecuten hasta que haya más entradas disponibles (para evitar consumir la CPU). De manera similar, si un programa anterior en la tubería está escribiendo datos más rápido de lo que un programa posterior puede leerlos, eventualmente el búfer de la tubería se llena y el escritor se bloquea: el sistema operativo lo cancela hasta que el lector vacía el búfer de la tubería, y luego puede seguir escribiendo de nuevo.
EDITAR
Si desea utilizar la salida de program1
como parámetros de la línea de comandos, puede utilizar las comillas inversas o el $()
sintaxis:
# Runs "program1 arg", and uses the output as the command-line arguments for
# program2
program2 `program1 arg`
# Same as above
program2 $(program1 arg)
los $()
se debe preferir la sintaxis, ya que son más claras y se pueden anidar.
Tubería no completa el primer comando antes de ejecutar el segundo. Las tuberías de Unix (y Linux) ejecutan todos los comandos al mismo tiempo. Un comando será suspendido si
Para la mayoría de los programas, la salida es amortiguado, lo que significa que el sistema operativo acumula una cantidad sustancial de salida (quizás unos 8000 caracteres) antes de pasarla a la siguiente etapa de la canalización. Este almacenamiento en búfer se utiliza para evitar demasiados cambios entre procesos y kernel.
Si desea que la salida en una canalización se envíe de inmediato, puede usar sin búfer I/O, que en C significa llamar a algo como fflush()
para asegurarse de que cualquier salida almacenada en búfer sea inmediatamente enviado al siguiente proceso. La entrada sin búfer también es posible, pero generalmente es innecesaria porque un proceso que no recibe entrada normalmente no espera a que se llene el búfer, sino que procesará cualquier entrada que pueda obtener.
Para aplicaciones típicas, no se recomienda la salida sin búfer; generalmente obtiene el mejor rendimiento con los valores predeterminados. Sin embargo, en su caso, donde desea hacer gráficos dinámicos inmediatamente, el primer proceso tiene la información disponible, definitivamente desea utilizar una salida sin búfer. Si está usando C, llamando fflush(stdout)
siempre que desee la salida enviada será suficiente.
Si sus programas se comunican usando stdin
y stdout
luego asegúrese de que está llamando fflush(stdout)
después de escribir o encontrar alguna forma de deshabilitar el almacenamiento en búfer de E/S estándar. La mejor referencia que se me ocurre que realmente describe cómo implementar mejor las canalizaciones en C/C++ es Programación Avanzada en el Entorno UNIX o Programación de redes UNIX: Volumen 2. Probablemente podrías empezar con un Este artículo así como.
Si sus dos programas insisten en leer y escribir archivos y no usan stdin/stdout, puede encontrar que puede usar un tubería con nombre en lugar de un archivo.
Cree una tubería con nombre con el comando mknod(1):
$ mknod /tmp/named-pipe p
Luego configure sus programas para leer y escribir en /tmp/named-pipe (use cualquier ruta/nombre que considere apropiado).
En este caso, ambos programas se ejecutarán en paralelo, bloqueándose según sea necesario cuando la tubería se llene/vacíe como se describe en las otras respuestas.
Mencionó una interfaz CLI para el programa 1 a continuación: si el programa 1 depende de la entrada interactiva, es probable que sea un mal candidato para la canalización directa, como muestra la respuesta de Adam.
–Harper Shelby
2 de julio de 2009 a las 2:46
Las tuberías en Windows son diferentes a las de Linux… Creo que Linux usa algún tipo de búfer en anillo y usa teorías de programación concurrentes (problema productor-consumidor, etc.) para funcionar bien. Creo que Windows espera hasta que se completa el primer programa antes de llamar al segundo.
– Ape-inago
2 de julio de 2009 a las 4:08