Comment utiliser les tuyaux sous Linux



Les canaux Linux permettent d’orchestrer la collaboration entre les outils de ligne de commande. Ils simplifient des opérations complexes et augmentent la productivité en transformant des commandes autonomes en une équipe unique. Découvrons comment cela fonctionne.

Les tubes, une omniprésence

Les tubes sont parmi les fonctionnalités de ligne de commande les plus pratiques des systèmes Linux et Unix. Leur utilisation est extrêmement diverse. Vous les croiserez systématiquement dans tous les articles traitant de la ligne de commande Linux, pas seulement sur ce site. L’examen d’articles récents a confirmé leur présence constante dans différents contextes et utilisations.

Grâce aux canaux, Linux propose des actions que l’interpréteur de commandes standard ne prend pas en charge. La philosophie de conception de Linux privilégie de multiples utilitaires simples qui excellent dans leur tâche spécifique, sans fonctionnalités superflues. L’adage « faire une chose et bien la faire » est ici primordial. Ainsi, il est possible de connecter des séquences de commandes par des tubes, transformant la sortie d’une commande en entrée d’une autre. Chaque commande apporte une compétence distincte à l’ensemble, formant rapidement une équipe efficace.

Un exemple simple

Imaginons un répertoire contenant des fichiers de divers types. Nous souhaitons savoir combien de fichiers d’un type particulier y sont présents. Il existe plusieurs méthodes pour y parvenir, mais l’objectif est ici de démontrer l’utilité des tubes.

La commande `ls` fournit aisément la liste des fichiers :

ls

Pour isoler le type de fichier désiré, la commande `grep` sera utilisée. Nous ciblerons les fichiers dont le nom ou l’extension incluent le terme « page ».

Le caractère spécial du shell « | », le tube, est employé pour rediriger la sortie de `ls` vers `grep`.

ls | grep "page"

`grep` affiche les lignes correspondant à son critère de recherche. On obtient ainsi une liste ne contenant que les fichiers « .page ».

Même cet exemple succinct illustre le fonctionnement des tubes. La sortie de `ls` n’est pas affichée directement dans la fenêtre du terminal, mais envoyée à `grep` comme donnée d’entrée. La sortie affichée provient de `grep`, dernière commande de la chaîne.

Extension de la chaîne de commandes

Améliorons cette séquence de commandes. Nous allons compter les fichiers « .page » en ajoutant la commande `wc`. L’option `-l` (nombre de lignes) sera utilisée avec `wc`. Notons également l’ajout de l’option `-l` (format long) à la commande `ls`. Cela nous servira ultérieurement.

ls -l | grep "page" | wc -l

`grep` n’est plus la dernière commande de la chaîne ; sa sortie n’est donc pas visible directement. La sortie de `grep` est envoyée à `wc`. L’affichage dans le terminal est celui de `wc`, signalant la présence de 69 fichiers « .page » dans le répertoire.

Allons plus loin. Nous remplacerons `wc` par `awk`. La sortie de `ls -l` comporte neuf colonnes. Awk affichera les colonnes cinq, trois et neuf, correspondant respectivement à la taille, au propriétaire et au nom du fichier.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'

Nous obtenons une liste de ces colonnes pour chaque fichier correspondant.

Cette sortie sera ensuite traitée par la commande `sort`. L’option `-n` (numérique) spécifie que la première colonne doit être triée comme des nombres.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n

La sortie est désormais triée par taille de fichier, avec notre sélection personnalisée de trois colonnes.

Ajout d’une commande supplémentaire

Terminons par l’ajout de la commande `tail`. Nous lui demanderons d’afficher uniquement les cinq dernières lignes de la sortie.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5

Cette commande équivaut à « montrer les cinq plus gros fichiers ‘.page’ de ce répertoire, classés par taille ». Bien qu’une commande unique ne réalise pas cette opération, l’utilisation de tubes nous a permis de la construire nous-mêmes. Cette séquence, ou toute autre commande élaborée, pourrait être enregistrée comme un alias ou une fonction shell afin d’éviter sa saisie répétée.

Voici le résultat :

Il est possible d’inverser l’ordre de taille en ajoutant l’option `-r` (reverse) à la commande `sort`, et en remplaçant `tail` par `head` pour afficher les lignes du début de la sortie.

Cette fois, les cinq plus gros fichiers « .page » sont listés du plus grand au plus petit :

Quelques exemples récents

Voici deux exemples intéressants tirés d’articles récents.

Certaines commandes, comme `xargs`, sont conçues pour recevoir des entrées. Par exemple, pour utiliser `wc` afin de compter les mots, caractères et lignes dans plusieurs fichiers, nous envoyons la sortie de `ls` à `xargs` qui transmet ensuite la liste des noms de fichiers à `wc` comme s’ils avaient été passés en paramètres de ligne de commande.

ls *.page | xargs wc

Le total des mots, caractères et lignes est affiché au bas de la fenêtre du terminal.

Voici une manière d’obtenir la liste triée des extensions de fichiers uniques dans le répertoire actuel, avec le décompte de chaque type.

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c

Cette commande réalise plusieurs opérations :

`ls`: Liste les fichiers du répertoire.
`rev`: Inverse le texte dans les noms de fichiers.
`cut`: Coupe la chaîne à la première occurrence du délimiteur spécifié « . ». Le texte suivant est supprimé.
`rev`: Inverse le texte restant, soit l’extension du nom de fichier.
`sort`: Trie la liste par ordre alphabétique.
`uniq`: Compte le nombre de chaque entrée unique de la liste.

La sortie affiche la liste des extensions de fichiers, triées par ordre alphabétique et avec le nombre de chaque type.

Tubes nommés

Il existe une autre catégorie de tubes, les tubes nommés. Les tubes des exemples précédents sont créés dynamiquement par le shell lors de l’exécution de la commande. Ils sont temporaires, disparaissant après utilisation, sans laisser de trace. Leur existence est liée à la durée de vie de la commande qui les utilise.

En revanche, les tubes nommés sont visibles dans le système de fichiers comme des objets persistants, consultables avec la commande `ls`. Ils sont persistants car ils survivent au redémarrage de l’ordinateur, même si les données non lues qu’ils contiennent sont alors supprimées.

Les tubes nommés étaient autrefois utilisés pour la communication entre processus, mais leur usage est devenu plus rare. Ils sont encore utilisés par certains, mais leur utilisation est moins courante. Néanmoins, pour la complétude, voici comment les utiliser.

Les tubes nommés sont créés avec la commande `mkfifo`. Cette commande créera un tube nommé appelé « geek-pipe » dans le répertoire courant.

mkfifo geek-pipe

Les détails du tube nommé sont visibles à l’aide de la commande `ls -l` :

ls -l geek-pipe

Le premier caractère « p » indique qu’il s’agit d’un tube. Un « d » signalerait un répertoire et un tiret « – » un fichier normal.

Utilisation du tube nommé

Mettons notre tube en pratique. Contrairement aux tubes sans nom, où les données sont transmises immédiatement, les données envoyées à un tube nommé y restent jusqu’à ce qu’elles soient lues. Les données sont conservées en mémoire, et la taille du tube ne varie pas selon qu’il contienne ou non des données.

Nous utiliserons deux fenêtres de terminal :

# Terminal-1

dans l’une et

# Terminal-2

dans l’autre pour une meilleure compréhension. Le « # » indique au shell qu’il s’agit d’un commentaire.

Reprenons la dernière commande, et redirigeons sa sortie vers le tube nommé, combinant tubes sans nom et nommé :

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe

L’invite de commande ne réapparaît pas immédiatement. C’est un signe que quelque chose est en cours.

Dans la deuxième fenêtre du terminal, exécutez :

cat < geek-pipe 

Le contenu du tube nommé est redirigé vers `cat`, qui l’affiche dans la deuxième fenêtre. Voici le résultat :

L’invite de commande est de nouveau disponible dans la première fenêtre du terminal.

Que s’est-il passé ?

Nous avons redirigé une partie de la sortie vers le tube nommé.
La première fenêtre du terminal n’a pas immédiatement affiché l’invite de commande.
Les données sont restées dans le tube jusqu’à ce qu’elles soient lues par la commande dans le deuxième terminal.
L’invite de commande est réapparue dans la première fenêtre une fois la lecture effectuée.

On pourrait penser que la commande exécutée dans la première fenêtre peut être lancée en arrière-plan, en ajoutant un `&` à la fin. Cela est vrai, et dans ce cas, l’invite de commande réapparaîtrait instantanément.

L’absence de processus en arrière-plan visait à mettre en évidence qu’un canal nommé est un processus bloquant. L’ajout de données à un tube nommé n’ouvre qu’une seule extrémité. L’autre extrémité reste fermée tant que les données ne sont pas lues. Le noyau suspend le processus dans la première fenêtre jusqu’à ce que la lecture des données soit effectuée.

La puissance des tubes

Les tubes nommés peuvent être perçus comme une curiosité de nos jours.

En revanche, les tubes Linux classiques sont parmi les outils les plus précieux de la ligne de commande. L’orchestration de multiples commandes en une seule opération cohérente donne une nouvelle dimension à l’utilisation du terminal.

Conseil : il est préférable de construire les commandes pipées en ajoutant progressivement une commande à la fois, s’assurant de la validité de chaque étape avant d’ajouter la suivante.