← Sommaire SkyLinux

Leçon 60 : Canaux nommés (Named Pipes / FIFO)

Tu connais les pipes | du shell ? Ils sont parfaits mais temporaires : les données transitent et disparaissent. Un canal nommé (aussi appelé FIFO pour First In, First Out) est un fichier spécial qui persiste. Tu peux y écrire depuis un terminal et lire depuis un autre, comme un vrai tuyau de communication entre processus.

Qu'est-ce qu'un canal nommé ?

Principe

Un canal nommé (named pipe ou FIFO) est un fichier spécial de type p. Contrairement à un pipe anonyme (|) qui n'existe que pendant l'exécution d'un processus, le FIFO existe dans le système de fichiers et peut être utilisé par n'importe quel processus, à n'importe quel moment.

# Créer un canal nommé mkfifo mondossier/mon-fifo # Vérifier son type ls -la mondossier/mon-fifo # Résultat : prw-r--r-- 1 david david 0 ... mon-fifo # ^ # |_ Le 'p' indique que c'est un pipe (FIFO)

Pourquoi utiliser un canal nommé ?

FIFO vs fichier classique vs pipe anonyme

CaractéristiqueCanal nommé (FIFO)Fichier classiquePipe anonyme |
Persistant après exécutionOui (jusqu'à suppression)OuiNon
Communication inter-processusOuiOui (via fichier)Oui (entre deux processus)
Plusieurs lecteurs simultanésOuiOuiOui
Plusieurs écrivains simultanésOuiOuiOui
Utilise le disqueNon (en mémoire)OuiNon
Accessible par nomOuiOuiNon (anonyme)

Créer et utiliser un canal nommé

Créer un FIFO avec mkfifo

# Syntaxe simple mkfifo /tmp/mon-fifo # Créer dans ton dossier personnel mkfifo ~/mon-fifo # Vérifier la création file ~/mon-fifo # Affiche : /home/david/mon-fifo: fifo (named pipe)

Écrire dans un FIFO

# Écrire du texte dans le FIFO echo "Bonjour depuis le terminal" > ~/mon-fifo # Écrire plusieurs lignes printf "Ligne 1\nLigne 2\nLigne 3\n" > ~/mon-fifo # Écrire depuis un fichier cat fichier.txt > ~/mon-fifo

Lire depuis un FIFO

# Lire le contenu (bloque jusqu'à données disponibles) cat ~/mon-fifo # Lire ligne par ligne avec read while IFS= read -r ligne; do echo "Reçu : $ligne" done < ~/mon-fifo

Exemple complet : communication entre deux terminaux

Ouvre deux terminaux. Dans le premier :

# Terminal 1 : créer le FIFO et lire mkfifo ~/chat-fifo cat ~/chat-fifo

Dans le second :

# Terminal 2 : écrire dans le FIFO echo "Salut, ça fonctionne !" > ~/chat-fifo

Le message apparaît dans le terminal 1. Chaque nouveau message envoyé depuis le terminal 2 sera affiché dans le terminal 1.

Cas d'utilisation pratiques

1. Rediriger la sortie de plusieurs programmes vers un seul fichier

# Créer un FIFO comme fichier de log central mkfifo /tmp/log-central # Terminal 1 : tous les logs arrivent ici cat /tmp/log-central > ~/application.log & # Terminal 2 : plusieurs programmes écrivent dedans echo "$(date) : Service démarré" > /tmp/log-central echo "$(date) : Utilisateur connecté" > /tmp/log-central nginx -g 'daemon off;' > /tmp/log-central 2>&1 & mysqld --log=/tmp/log-central &

2. Débogage en temps réel

# Créer un FIFO pour capturer les logs mkfifo ~/debug-pipe # Terminal 1 : surveiller les logs en direct tail -f ~/debug-pipe & # Terminal 2 : ta commande génère des logs ./mon-script.sh > ~/debug-pipe 2>&1

3. Communication entre un script parent et un script enfant

# script-parent.sh #!/bin/bash mkfifo /tmp/pipe-parent # Démarrer l'enfant en arrière-plan bash script-enfant.sh & # Envoyer des commandes echo "START" > /tmp/pipe-parent sleep 5 echo "STOP" > /tmp/pipe-parent sleep 1 echo "QUIT" > /tmp/pipe-parent # Nettoyer rm -f /tmp/pipe-parent
# script-enfant.sh #!/bin/bash while true; do IFS= read -r cmd < /tmp/pipe-parent case "$cmd" in START) echo "Enfant : démarrage..." ;; STOP) echo "Enfant : arrêt..." ;; QUIT) echo "Enfant : au revoir !"; exit 0 ;; esac done

4. Faire communiquer un serveur et un client sans réseau

# Serveur : lit les commandes depuis le FIFO mkfifo /tmp/serveur-fifo while IFS= read -r cmd < /tmp/serveur-fifo; do echo "Commande reçue : $cmd" # Exécuter la commande eval "$cmd" done > /tmp/serveur-output 2>&1 &
# Client : envoyer des commandes echo "ls -la /home" > /tmp/serveur-fifo echo "df -h" > /tmp/serveur-fifo # Lire les résultats cat /tmp/serveur-output

5. pipewire / audio via FIFO (exemple simplification)

# Si un programme ne peut qu'écrire dans un fichier, utiliser un FIFO mkfifo /tmp/audio-stream cat /tmp/audio-stream | ton-programme-audio &

Les commandes principales

mkfifo — Créer un FIFO

# Syntaxe de base mkfifo /chemin/vers/fifo # Avec permissions personnalisées mkfifo -m 600 /tmp/fifo-prive # Créer plusieurs mkfifo ~/pipe1 ~/pipe2 ~/pipe3

file — Vérifier le type

file ~/mon-fifo # Affiche : /home/david/mon-fifo: fifo (named pipe)

ls -la — Identifier les FIFO

ls -la /tmp/*.fifo /tmp/*.pipe 2>/dev/null # ou lister tout ls -la | grep '^p'

Comportement de lecture et écriture

Principe fondamental : bloquant

Les opérations de lecture et d'écriture sur un FIFO sont bloquantes par défaut. Cela signifie :

Écriture sans blocage (non-blockant)

# Ouvrir le FIFO en mode non-bloquant exec 3> /tmp/mon-fifo echo "Texte" >&3

Lecture sans blocage

# Utiliser timeout pour ne pas bloquer indéfiniment timeout 5 cat /tmp/mon-fifo # Affiche les données ou rien si timeout

Ouvrir un FIFO dans les deux sens

Si tu veux qu'un processus lise et écrive sur le même FIFO, ouvre-le dans les deux directions :

# Processus bidirectionnel mkfifo /tmp/fifo-bidir # Ouvre une extrémité en lecture, l'autre en écriture exec 3<>/tmp/fifo-bidir # Écrire echo "Question" >&3 # Lire la réponse timeout 5 cat <&3

Bonnes pratiques

Erreurs courantes et solutions

Erreur : write bloque indéfiniment

# Personne ne lit le FIFO, l'écriture bloque echo "test" > ~/mon-fifo # ^ bloque ici # Solution : avoir un processus qui lit, ou utiliser non-bloquant timeout 1 cat ~/mon-fifo & sleep 0.5 echo "test" > ~/mon-fifo

Erreur : ls montre le FIFO mais cat ne renvoie rien

# Le FIFO est vide (les données ont déjà été lues) # ou personne n'a encore écrit dedans # Vérifier que l'écrivain a bien envoyé quelque chose # Un lecteur précédent a tout consommé # Recommencer : # Terminal 1 : cat ~/mon-fifo (lance le lecteur) # Terminal 2 : echo "msg" > ~/mon-fifo (envoie après)

Le FIFO disparaît après un reboot

# Les FIFO sont en mémoire, pas sur disque # Solution : créer le FIFO au démarrage du script if [ ! -p ~/mon-fifo ]; then mkfifo ~/mon-fifo fi

Plusieurs écrivains, un lecteur : données mélangées

# Si plusieurs programmes écrivent simultanément # Les lignes peuvent se mélanger # Solution : utiliser un lock ou unbuffering { flock -n 3 || true; echo "msg"; } > ~/mon-fifo

Résumé

CommandeUsage
mkfifo /chemin/fifoCréer un canal nommé (FIFO)
file /chemin/fifoVérifier que c'est bien un FIFO
ls -la | grep '^p'Lister tous les FIFO du répertoire
echo "msg" > ~/fifoÉcrire dans un FIFO
cat ~/fifoLire depuis un FIFO
rm ~/fifoSupprimer un FIFO
timeout N cat ~/fifoLecture avec timeout (non-bloquante)

Les canaux nommés sont un outil puissant pour la communication inter-processus sur Linux. Ils permettent de créer des architectures simples sans réseau ni configuration avancée. Maîtrise-les et tu disposeras d'un outil supplémentaire pour structurer tes scripts et automatisations.