Que fait le symbole de pipe linux “|”? [dupliquer]

23

Cette question a déjà une réponse ici:

Voici une commande qui trie les fichiers d'un dossier dans l'ordre inverse

ls | sort -r

Que fait le |symbole dans cette commande?

Ce que je recherche vraiment ici est une explication de haut niveau (facile à comprendre) des tuyaux pour les débutants sous Linux. Je vois d’autres questions sur les pipes ici sur Superuser, mais rien qui suscite une réponse expliquant simplement ce qu’elles font et en quoi elles diffèrent de la redirection (le symbole >ou <).

ccalvert
la source
7
Cela n’a rien à voir avec Linux (qui est un noyau). Les pipes sont en général un moyen de rediriger les entrées / sorties, dans un shell comme bash, ce n’est pas différent. La seule chose spéciale à propos de a |est qu’elle n’utilise pas de nom. La sortie de la commande à main gauche est directement transmise à l’entrée de la commande située du côté droit du tuyau.
Andon M. Coleman
Pour une leçon d'histoire sur le sujet, lisez linfo.org/pipe.html
Fredrik Pihl
ls -1r(Notez le premier argument) devrait produire un résultat similaire à ls | sort -r.
Ivan Chau
J'aime expliquer cela de la manière suivante: un tube prend le résultat d’une commande et le rend utilisable pour une commande suivante. Par exemple, vous pouvez faire cat /somefile | grep cool. Cela prendra la sortie de somefile et le rendra disponible pour grep, puis grep imprimera toutes les lignes contenant le mot cool.
JohnDoea le

Réponses:

26

Ce qui suit est un peu simplifié pour aider les nouveaux utilisateurs.

Eh bien, tout d’abord, il est nécessaire de comprendre le concept d’entrée standard et de sortie standard.

Sous Linux et d'autres systèmes d'exploitation de type UNIX, chaque processus a une entrée standard ( stdin) et une sortie standard ( stdout). La situation habituelle est celle de stdinvotre clavier et celle de stdoutvotre écran ou de votre terminal.

Ainsi, lorsque vous exécutez ls, il renvoie sa sortie à stdout. Si vous ne faites rien d’autre, il s’affichera sur votre écran ou votre terminal.

Désormais, certaines commandes Linux interagissent avec l'utilisateur et l'utilisent stdin, notamment l'éditeur de texte. Il lit à partir de stdinpour accepter vos frappes au clavier, faire des choses, puis écrit des choses à stdout.

Cependant, il existe également des commandes non interactives ou "filtre" qui ne fonctionnent PAS de manière interactive, mais qui nécessitent un tas de données. Ces commandes vont prendre tout ce qu’il stdina, faire quelque chose, puis le jeter àstdout

Regardons une autre commande appelée du- représente l'utilisation du disque. du /usr, par exemple, affichera ( stdoutcomme toute autre commande Linux) une liste de tous les fichiers de ce répertoire et sa taille:

# du /usr
2312    /usr/games
124     /usr/lib/tc
692     /usr/lib/rygel-1.0
400     /usr/lib/apt/methods
40      /usr/lib/apt/solvers
444     /usr/lib/apt
6772    /usr/lib/gnash

Comme vous pouvez le constater dès le départ, il n’est pas trié et vous souhaitez probablement le faire par ordre de taille.

sortest l’une de ces commandes "filter" qui vont prendre un tas de choses stdinet les trier.

Donc, si on fait ça:

# du /usr | sort -nr

nous obtenons ceci, qui est un peu mieux:

4213348 /usr
2070308 /usr/lib
1747764 /usr/share
583668  /usr/lib/vmware
501700  /usr/share/locale
366476  /usr/lib/x86_64-linux-gnu
318660  /usr/lib/libreoffice
295388  /usr/lib/vmware/modules
290376  /usr/lib/vmware/modules/binary
279056  /usr/lib/libreoffice/program
216980  /usr/share/icons

Et vous pouvez maintenant voir que le "tuyau" connecte la stdoutcommande d'une commande à la commande stdind'une autre. En règle générale, vous l'utiliserez dans des situations telles que celle où vous souhaitez filtrer, trier ou manipuler de toute autre manière la sortie d'une commande. Ils peuvent être mis en cascade si vous souhaitez traiter la sortie via plusieurs commandes de type filtre.

Si vous tapez sortseul, il essaiera toujours de lire stdin. Puisque stdinest connecté à votre clavier, il attendra que vous tapiez et traitiez les choses jusqu'à ce que vous appuyiez sur Ctrl-D. Cela ne vous le demandera pas car ce n'est pas vraiment fait pour être utilisé de manière interactive.

Il est possible qu'un programme indique s'il stdinest interactif ou non. Certains programmes peuvent donc agir différemment si vous les publiez eux-mêmes ou à la fin d'un tuyau.

En outre, si vous programmez un programme qui ne fonctionne que de manière interactive, vous vipasserez un mauvais moment.

Les pipes diffèrent de la redirection en ce sens que les données sont brassées d'une commande à l'autre sans être stockées nulle part. Ainsi, dans l'exemple ci-dessus, dula sortie de n'est pas stockée nulle part. La plupart du temps, vous ne le souhaitez pas avec les pipes, car l’utilisation des pipes a pour but de traiter la sortie d’une commande, mais il existe une commande teequi vous permet d’avoir votre gâteau et de le manger aussi. copier ce qu’il reçoit stdindans les deux stdoutfichiers et dans un fichier de votre choix. Vous pouvez aussi probablement le faire bashavec une syntaxe mystérieuse impliquant des esperluettes et des crochets que je ne connais pas.

LawrenceC
la source
Notez que ce n'est pas unique à Linux, ni même à POSIX. La plupart des shell (tous?) Sous Windows le font aussi. Et probablement d'autres systèmes d'exploitation.
Bob
Je connais le concept de stdinet stdoutest différent sous Windows de celui sous Linux, bien que probablement pas beaucoup du point de vue de Windows cmd.exeou de Powershell.
LawrenceC
Je suis assez curieux de savoir en quoi c'est différent - pourriez-vous expliquer? Peut-être dans le chat si les commentaires ne sont pas un bon endroit pour cela.
Bob
1
Les programmes Win32 ont très certainement une entrée et une sortie standard. Par exemple, vous pouvez récupérer le descripteur standard d'entrée, de sortie ou d'erreur de votre processus avec la fonction Win32 GetStdHandle(). Il est également simple de rediriger les flux standard d'un processus [enfant] engendré avec .NET, qui, je crois, mappe aux fonctions Win32 (mais je ne suis pas sûr à 100% de cela - je ne suis pas un dev Win32).
Bob
1
Ah, voici l’équivalent Win32, en définissant les paramètres appropriés dans la STARTUPINFOstructure pour CreateProcess().
Bob
27

Si vous êtes à l'aise avec la redirection des entrées et des sorties, l'explication est vraiment très simple.

Command1 | Command2

fait la même chose que

Command1 > tempfile
Command2 < tempfile

mais sans tempfile. La sortie de Command1est directement connectée à l'entrée de Command2et le transfert s'effectue en mémoire.

Daniel B
la source
Je peux me tromper mais je pense que le fichier temporaire existe même dans la syntaxe du tuyau. Ça n'a tout simplement pas de nom.
Taemyr
3
Non. Aucune opération de système de fichiers n'est impliquée lors du transfert d'une sortie d'une commande vers l'entrée d'une autre commande.
Daniel B
1
Cependant, sous DOS (et probablement Windows), un fichier temporaire est créé par le tube. Pas * nix, mais rien ne vaut la différence.
Jeremy J Starcher
Je suis à peu près sûr que ce n'est pas correct. Process Monitor signale le non CreateFileou WriteFileappelle à sauvegarder votre réclamation. / edit: C'est pour la partie Windows, bien sûr.
Daniel B
3

Vraiment, si vous voulez savoir ce que font les pipes et la différence entre> et |, allez dans un répertoire avec beaucoup de fichiers, et

depuis un terminal ls contre ls | more (ou depuis Windows avec DIR et DIR | MORE)

Si vous avez utilisé> more, vous verrez qu'il crée un fichier appelé "more" au lieu d'envoyer le résultat de ls à la commande "more". Donc, si quelqu'un faisait> plus, ce serait probablement une erreur, on ne ferait pas> plus, vous feriez> fichier1. Plus est une commande bien connue.

Le <comme le> sert également à lier une commande et un fichier, plutôt qu’une commande à une commande. Mais alors que> envoie la sortie d'une commande à un fichier, le <envoie un fichier en tant qu'entrée à une commande. J'utilise rarement <comme j'utilise habituellement cat file1 | envoyer la sortie d'un fichier à une commande.

$ grep un <fichier1 abc

$ cat file1 | grep a abc

grep avec 2 paramètres est de la forme fichier de motif grep. grep avec un paramètre est le motif grep. Et vous pouvez lui envoyer le fichier en lui passant le contenu du fichier ou en utilisant <. Si vous utilisez <, vous écrivez d'abord le nom de la commande, puis le nom du fichier après la commande <file. Si vous utilisez | pour diriger le contenu d'un fichier, utilisez cat file1 | commander.

De plus, de nombreuses commandes prennent quand même un fichier en entrée, donc grep un fichier1 fonctionnera, tout comme cat file1 | grep a et grep a <fichier1.

Je faisais des pipes (|) et> sur DOS il y a 15 ans.

Pour résumer comment | diffère de <et> - Le tube est situé entre 2 commandes. Les <et> sont situés entre une commande et un fichier. Le> est sorti dans un fichier. Le <est une entrée d'un fichier.

barlop
la source
3

Le caractère de canal ( |) connecte la sortie d'un programme à l'entrée d'un autre.

Dans cet exemple, echole mot est imprimé helloet wc -ccompte le nombre de caractères de son entrée:

echo hello | wc -c
bbaassssiiee
la source
Je pense que vous devriez dire immédiatement que l’écho produira "bonjour \ n". Vous ne dites pas au PO d’étudier, vous le dites à tous ceux qui lisent votre réponse. Pourquoi multiplier cette perte de temps?
Rodrigo
Merci pour les commentaires, j'ai raccourci ma réponse.
bbaassssiiee
2

Pour comprendre cela, essayez vous-même:

sort -r

Maintenant, vous êtes avec un curseur, et il ne fait rien. Que se passe-t-il si vous tapez des données?

1
2
3
5
4

Toujours rien, non? Maintenant, appuyez sur ctrl + d

5
4
3
2
1

Ainsi, quelle sorte est, il prend une entrée (ce que vous avez tapé), fait quelque chose avec elle (une sorte) et le restitue en sortie. La lscommande ne prend pas d'entrée, elle génère seulement une sortie. Le symbole de canal prend la sortie de lset l’alimente en entrée de la sortcommande.

>ne transmet pas la sortie à un programme, mais stocke la sortie sous forme de fichier. <utilise un fichier comme entrée.

Jornane
la source