En Linux (y Unix en general) cada proceso tiene tres descriptores de archivo por defecto:
- fd # 0 representa la entrada estándar del proceso
- fd # 1 representa la salida estándar del proceso
- fd # 2 representa la salida de error estándar del proceso
Normalmente, cuando se ejecuta un programa sencillo estos descriptores de archivo por defecto están configurados de la siguiente manera:
- de entrada por defecto se lee desde el teclado
- de salida estándar está configurado para ser el monitor
- Error estándar está configurado para ser el monitor también
Bash proporciona varios operadores para cambiar este comportamiento (Eche un vistazo a los operadores>, >> y < por ejemplo). Por lo tanto, puede redirigir la salida a algo que no sea la salida estándar o leer su entrada de otra secuencia diferente al teclado. Especialmente interesante es el caso cuando dos programas son que colaboran con de tal manera que uno utiliza la salida del otro como su entrada. Para facilitar esta colaboración, Bash proporciona el operador de tubería |. Tenga en cuenta el uso de la colaboración en lugar de encadenando. Evité el uso de este término ya que, de hecho, una tubería no es secuencial. Una línea de comandos normal con tubos tiene el siguiente aspecto:
> program_1 | program_2 | ... | program_n
La línea de comandos anterior es un poco engañosa: el usuario podría pensar que program_2 toma su entrada una vez que el program_1 ha terminado su ejecución, lo cual no es correcto.De hecho, lo que Bash hace es lanzar ALL los programas en paralelo y configura las salidas de entrada en consecuencia para que cada programa obtenga su entrada del anterior y entregue su salida al siguiente (en el orden establecido de la línea de comando).
A continuación se muestra un ejemplo simple de Creating pipe in C para crear un conducto entre un proceso primario y otro secundario. La parte importante es la llamada a la tubería() y cómo el padre cierra fd 1 (lado de escritura) y cómo el niño cierra fd 1 (lado de escritura). Tenga en cuenta que la tubería es un canal de comunicación unidireccional. Por lo tanto, los datos solo pueden fluir en una dirección: fd 1 hacia fd [0]. Para obtener más información, consulte la página de manual de pipe().
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
Por último, pero no menos importante, cuando se tiene una línea de comandos en la forma:
> program_1 | program_2 | program_3
El código de retorno de la totalidad de las líneas se establece en el último comando . En este caso program_3. Si desea obtener un código de retorno intermedio, debe configurar el pipefail o obtenerlo del PIPESTATUS.
Las tuberías no pasan la salida como parámetro. Las tuberías conectan STDOUT a STDIN. Algunos comandos deben ser instruidos específicamente para mirar STDIN (generalmente dando un guión en lugar de un nombre de archivo) antes de que puedan ser utilizados en las tuberías. – quanticle
Muy bien, gracias por la corrección! Actualicé mi respuesta. – franka
Es muy importante tener en cuenta que también lo transmite. El proceso de la derecha no necesita esperar a que termine el proceso de la izquierda antes de que pueda comenzar a funcionar. Entonces cosas como 'sí | rm -r * 'como alternativa al trabajo' rm -rf * 'aunque sí nunca termina de ejecutar – Paulpro