Comment comprendre les tuyaux

21

Quand je viens d'utiliser de la pipe en bash, je n'y ai pas pensé davantage. Mais quand j'ai lu un exemple de code C utilisant pipe () d'appel système avec fork (), je me demande comment comprendre les pipes, y compris les pipes anonymes et les pipes nommées.

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

Cependant, à partir d'exemples de canaux nommés, j'ai également appris que l'utilisation de canaux présente un avantage en termes de performances spatiales et temporelles par rapport à l'utilisation explicite de fichiers temporaires, probablement parce qu'aucun fichier n'est impliqué dans l'implémentation de canaux. Les canaux semblent également ne pas stocker de données comme le font les fichiers. Je doute donc qu'une pipe soit en fait un fichier.

Tim
la source

Réponses:

23

Concernant votre question de performances, les canaux sont plus efficaces que les fichiers car aucune E / S disque n'est nécessaire. Il cmd1 | cmd2est donc plus efficace que cmd1 > tmpfile; cmd2 < tmpfile(cela peut ne pas être vrai s'il tmpfileest sauvegardé sur un disque RAM ou un autre périphérique de mémoire en tant que canal nommé; mais s'il s'agit d'un canal nommé, il cmd1doit être exécuté en arrière-plan car sa sortie peut bloquer si le canal est plein ). Si vous avez besoin du résultat de cmd1et devez toujours envoyer sa sortie à cmd2, vous devriez cmd1 | tee tmpfile | cmd2autoriser cmd1et cmd2exécuter en parallèle en évitant les opérations de lecture sur disque cmd2.

Les canaux nommés sont utiles si de nombreux processus 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 fichiers . Je mets les fichiers en italique car les canaux nommés ne sont pas exactement des fichiers d'un point de vue de stockage car ils résident en mémoire et ont une taille de tampon fixe, même s'ils ont une entrée de système de fichiers (à des fins de référence). D'autres choses sous UNIX ont des entrées de système de fichiers sans être des fichiers: pensez simplement à /dev/nullou à d'autres entrées dans /devou /proc.

Comme les canaux (nommés et non nommés) ont une taille de tampon fixe, les opérations de lecture / écriture peuvent se bloquer, ce qui fait passer le processus de lecture / écriture dans l'état IOWait. De plus, quand recevez-vous un EOF lors de la lecture à partir d'un tampon mémoire? Les règles sur ce comportement sont bien définies et peuvent être trouvées chez l'homme.

Une chose que vous ne pouvez pas faire avec les canaux (nommés et non nommés) est la recherche dans les données. Comme ils sont implémentés à l'aide d'un tampon mémoire, cela est compréhensible.

À propos "everything in Linux/Unix is a file", je ne suis pas d'accord. Les canaux nommés ont des entrées de système de fichiers, mais ne sont pas exactement des fichiers. Les canaux sans nom n'ont pas d'entrées de système de fichiers (sauf peut-être dans /proc). Cependant, la plupart des opérations d'E / S sous UNIX sont effectuées à l'aide d'une fonction de lecture / écriture qui nécessite un descripteur de fichier , y compris un canal (et un socket) sans nom. Je ne pense pas que nous puissions dire cela "everything in Linux/Unix is a file", mais nous pouvons certainement le dire "most IO in Linux/Unix is done using a file descriptor".

jfg956
la source
Merci! Les deux commandes sont-elles connectées par un tuyau qui s'exécute en parallèle, au lieu que le second commence à s'exécuter une fois le premier terminé?
Tim
Oui, les 2 commandes sont exécutées en parallèle. S'ils ne l'étaient pas et la 1ère sortie plus que le tampon, elle serait bloquée. Vous pouvez l'essayer en exécutant cmd1 > fifoet cmd2 < fifodans 2 shells différents, en créant le tube nommé avec mkfifo fifo.
jfg956
Un autre test que vous pouvez faire est de tuer cmd2alors qu'il cmd1est toujours en cours d'exécution: cmd1arrêtera probablement de signaler un message de tuyau cassé.
jfg956
Merci! que voulez-vous dire serait bloqué? Si cela se produit, cela signifie-t-il que la date dans le flux après le bloc sera perdue?
Tim
2
Les données ne sont pas perdues. Si le tampon du tuyau est plein, cmd1l'écriture de dans le tuyau ne sera renvoyée que lorsque cmd2les données lues dans le tuyau auront été lues. De la même manière, cmd2la lecture d'un tube se bloquera si le tampon est vide jusqu'à ce qu'il soit cmd1écrit dans le tube.
jfg956
4

Deux des principes fondamentaux de la philosophie UNIX sont

  1. Faire de petits programmes qui font bien une chose.
  2. et attendez-vous à ce que la sortie de chaque programme devienne l'entrée d'un autre programme,
    encore inconnu.

    L'utilisation de tuyaux vous permet de tirer parti des effets de ces deux
    principes fondamentaux de conception pour créer des chaînes de commandes extrêmement puissantes pour atteindre le résultat souhaité.

    La plupart des programmes en ligne de commande qui fonctionnent sur des fichiers peuvent également accepter une entrée sur entrée standard (entrée via le clavier) et une sortie sur sortie standard (impression à l'
    écran).

    Certaines commandes sont conçues pour fonctionner uniquement dans un canal et ne peuvent pas fonctionner directement sur les fichiers.

    par exemple trcommande

  ls -C | tr 'a-z' 'A-Z'
    cmd1 | cmd2
  • Envoie STDOUT de cmd1 à STDIN de cmd2 au lieu de l'écran.

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

    En bref, vous Pipes is character (|)pouvez connecter des commandes.

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

       ls - /etc | less 

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

       echo "test print" | lpr 

    Un canal traditionnel est "sans nom" car il existe de manière anonyme et ne persiste que tant que le processus est en cours d'exécution. Un canal nommé est persistant système et existe au-delà de la durée de vie du processus et doit être supprimé une fois qu'il n'est plus utilisé. Les processus s'attachent généralement au canal nommé (apparaissant généralement sous forme de fichier) pour effectuer la communication inter-processus (IPC).

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

mr_eclair
la source
3

Pour compléter les autres réponses ...

stdin et stdout sont des descripteurs de fichiers et sont lus et écrits comme s'il s'agissait de fichiers. par conséquent, vous pouvez le faire echo hi | grep hi, et il remplacera la sortie standard d'écho par un tuyau et remplacera stdin de grep à l'autre extrémité de ce tuyau.

user606723
la source
1

Tout est un fichier.

Si nous prenons l'expression trop à la lettre, nous finirions par avoir le sens de «nous n'avons que des fichiers et rien d'autre». Ce n'est pas la bonne interprétation, alors c'est quoi.

Lorsque nous disons «Tout est un fichier», nous ne disons pas que tout est stocké sur un disque. Nous disons que tout ressemble à un fichier, peut être lu, écrit.

Sous Unix, une fois qu'un fichier ou un non-fichier est ouvert, il peut être traité comme un fichier. Cependant, tous les fichiers ne prennent pas en charge toutes les opérations. Par exemple, certains fichiers (qui ne sont pas des fichiers), ne prennent pas en charge la recherche: ils doivent être lus / écrits dans l'ordre (c'est le cas des tuyaux et des sockets).

Tout a un nom de fichier (sur certains systèmes: par exemple Debian Gnu / Linux, et beaucoup d'autres Gnu / Linux).

  • Tous les fichiers ouverts obtiennent un nom de fichier. Voir/proc/self/fd/…
  • Les sockets réseau peuvent être ouvertes avec un nom de fichier, voir /dev/tcp
    par exemplecat </dev/tcp/towel.blinkenlights.nl/23
ctrl-alt-delor
la source
Cette dernière partie n'est valable que sur les systèmes dotés d'un /procsystème de fichiers et sur les systèmes (ou shells) qui fournissent une /dev/tcpstructure de fichiers.
Kusalananda