Comment comprendre les tuyaux

Quand je viens d'utiliser pipe dans bash, je n'y ai plus pensé. Mais quand je lis un exemple de code C en utilisant system call pipe () avec fork (), je me request comment comprendre les pipes, y compris les pipes anonymes et les pipes nommées.

On entend souvent que "tout dans Linux / Unix est un file". Je me request si un tuyau est en fait un file de sorte qu'une partie il se connecte écrit dans le file de pipe, et l'autre partie lit du file de pipe? Si oui, où est créé le file de pipe pour un tuyau anonyme? Dans / tmp, / dev, ou …?

Cependant, à partir d'exemples de pipes nommés, j'ai aussi appris que l'utilisation de pipes a un avantage de time et d'espace par rapport à l'utilisation explicite de files temporaires, probablement parce qu'il n'y a pas de files impliqués dans la mise en œuvre des pipes. De même, les tuyaux ne semblent pas stocker datatables comme le font les files. Je doute donc qu'une pipe soit en réalité un file.

A propos de votre question de performance, les canaux sont plus efficaces que les files, car aucun disque d'ES n'est nécessaire. Donc cmd1 | cmd2 cmd1 | cmd2 est plus efficace que cmd1 > tmpfile; cmd2 < tmpfile cmd1 > tmpfile; cmd2 < tmpfile (cela peut ne pas être vrai si tmpfile est sauvegardé sur un disque RAM ou un autre périphérique de memory en tant que canal nommé, mais s'il s'agit d'un canal nommé, cmd1 doit être exécuté en arrière-plan, ). Si vous avez besoin du résultat de cmd1 et que vous devez toujours envoyer sa sortie à cmd2 , vous devriez cmd1 | tee tmpfile | cmd2 cmd1 | tee tmpfile | cmd2 cmd1 | tee tmpfile | cmd2 qui permettra à cmd1 et cmd2 de fonctionner en parallèle en évitant les opérations de lecture de disque de cmd2 .

Les canaux nommés sont utiles si de nombreux process lisent / écrivent sur le même canal. Ils peuvent également être utiles lorsqu'un programme n'est pas conçu pour utiliser stdin / stdout pour son IO devant utiliser des files . Je mets des files en italique car les pipes nommés ne sont pas exactement des files du sharepoint vue du stockage car ils résident en memory et ont une taille de tampon fixe, même s'ils ont une input de système de files . D'autres choses dans UNIX ont des inputs de système de files sans être des files: pensez simplement à /dev/null ou à d'autres inputs dans /dev ou /proc .

Comme les canaux (nommés et non nommés) ont une taille de memory tampon fixe, les opérations de lecture / écriture peuvent bloquer, ce qui entraîne l'exécution du process de lecture / écriture dans l'état IOWait. Aussi, quand recevez-vous un EOF lors de la lecture d'un tampon memory? Les règles sur ce comportement sont bien définies et peuvent être trouvées dans l'homme.

Une chose que vous ne pouvez pas faire avec des tuyaux (nommé et sans nom) est de chercher dans datatables. Comme ils sont implémentés en utilisant un tampon memory, cela est compréhensible.

A propos de "everything in Linux/Unix is a file" , je ne suis pas d'accord. Les canaux nommés ont des inputs de système de files, mais ne sont pas exactement le file. Les canaux sans nom n'ont pas d'inputs de système de files (sauf peut-être dans /proc ). Cependant, la plupart des opérations d'E / S sur UNIX sont effectuées en utilisant la fonction de lecture / écriture qui nécessite un descripteur de file , y compris un nom de canal (et un socket). Je ne pense pas que l'on puisse dire que "everything in Linux/Unix is a file" , mais on peut sûrement dire que "most IO in Linux/Unix is done using a file descriptor" .

Deux des principes de base de la philosophie UNIX sont

  1. Faire de petits programmes qui font bien une chose.
  2. et attendez que le résultat de chaque programme devienne l'intrant d'un autre
    encore inconnu, programme.

    L'utilisation de tuyaux vous permet de tirer parti des effets de ces deux templates
    les fondamentaux pour créer des strings de commands extrêmement puissantes pour atteindre le résultat souhaité.

    La plupart des programmes en command line qui fonctionnent sur des files peuvent également accepter les inputs sur input standard (input par keyboard) et sortie vers sortie standard (printing activée
    écran).

    Certaines commands sont conçues pour fonctionner uniquement dans un tuyau ne peut pas fonctionner directement sur les files.

    par exemple command tr

  ls -C | tr 'az' 'AZ' 
  cmd1 | cmd2 
  • Envoie STDOUT de cmd1 à STDIN de cmd2 au lieu de l'écran.

  • STDERR n'est pas transmis à travers les tuyaux.

    En bref Pipes is character (|) peut connecter des commands.

    Toute command qui écrit dans STDOUT peut être utilisée sur le côté gauche du tube.

      ls - /etc | less 

    Toute command qui lit à partir de STDIN peut être utilisée sur le côté droit d'un tuyau.

      echo "test print" | lpr 

    Une pipe traditionnelle est "sans nom" car elle existe de manière anonyme et ne persiste que tant que le process est en cours. Un canal nommé est persistant dans le système et existe au-delà de la durée du process et doit être supprimé une fois qu'il n'est plus utilisé. Les process se connectent généralement au canal nommé (apparaissant généralement en tant que file) pour effectuer une communication inter-process (IPC).

source: http://en.wikipedia.org/wiki/Named_pipe

Pour compléter les autres réponses …

stdin et stdout sont des descripteurs de files et sont lus et écrits comme s'il s'agissait de files. donc vous pouvez faire echo hi | grep hi echo hi | grep hi , et il replacea le stdout d'echo avec un tuyau et replacea stdin de grep à l'autre extrémité de ce tuyau.