Sous Linux (et Unix en général), chaque processus dispose de trois descripteurs de fichiers par défaut :
- fd #0 Représente l'entrée standard du processus
- fd #1 Représente la sortie standard du processus
- fd #2 Représente la sortie d'erreur standard du processus
Normalement, lorsque vous exécutez un programme simple, ces descripteurs de fichiers sont configurés par défaut comme suit :
- l'entrée par défaut est lue à partir du clavier
- La sortie standard est configurée pour être le moniteur
- L'erreur standard est configurée pour être également le moniteur
Bash propose plusieurs opérateurs pour modifier ce comportement (voir les opérateurs >, >> et < par exemple). Ainsi, vous pouvez rediriger la sortie vers autre chose que la sortie standard ou lire votre entrée à partir d'un autre flux que le clavier. C'est particulièrement intéressant dans le cas où deux programmes sont collaboration de manière à ce que l'un utilise la sortie de l'autre comme entrée. Pour faciliter cette collaboration, Bash fournit l'opérateur pipe |
. Veuillez noter l'utilisation de collaboration au lieu de enchaînement . J'ai évité d'utiliser ce terme car, en fait, un tuyau n'est pas séquentiel . Une ligne de commande normale avec des tuyaux présente l'aspect suivant :
> program_1 | program_2 | ... | program_n
La ligne de commande ci-dessus est un peu trompeuse : l'utilisateur pourrait penser que le programme_2 reçoit son entrée une fois que le programme_1 a terminé son exécution, ce qui n'est pas correct. En fait, ce que fait bash est de lancer TOUS les programmes en parallèle et configure les entrées-sorties en conséquence afin que chaque programme reçoive son entrée du précédent et délivre sa sortie au suivant (dans l'ordre établi par la ligne de commande).
Voici un exemple simple de Création d'un tuyau en C de créer un tuyau entre un processus parent et un processus enfant. La partie importante est l'appel à la fonction pipe() et la façon dont le parent ferme fd 1 (côté écriture) et comment l'enfant ferme fd 1 (côté écriture). Veuillez noter que le tuyau est un unidirectionnel canal de communication. Les données ne peuvent donc circuler que dans un seul sens : fd 1 vers fd[0]. Pour plus d'informations, consultez la page de manuel 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);
}
Enfin, lorsque vous avez une ligne de commande dans le formulaire :
> program_1 | program_2 | program_3
Le code de retour de l'ensemble de la ligne est fixé à la valeur dernier commande. Dans ce cas, il s'agit de program_3. Si vous souhaitez obtenir un code de retour intermédiaire, vous devez définir le paramètre queue de pipe ou l'obtenir auprès du PIPESTATUS .