IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

questions sur les pipes ?


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Par défaut questions sur les pipes ?
    slt tt le monde :

    j'ai quelques questions concernant les pipes :

    1- d'abord , quand j'ai 3 commandes par exemples qui s'executent en pipe :
    commande1 | commande2 | commande3
    je dois créer en premier un seul tube ( int tube[2] ) que je vais utiliser d'abord entre
    commande 1 et commande2 , puis entre commande 2 et commande 3 ,ou bien je
    dois créer pour chaque | un tube ?

    2- et quand je crée des processus aux quels je vais faire du recouvrement pour
    chacun d'eux ( si je remplace le programme de chaque processus par un
    executable d'une commande de linux) , exemple : mkdir rep1 | ls
    que dois passer la commande mkdir a la commande ls comme paramétre ?
    je pense que ça se réalise a l'aide de la fonction write mais comment ? et que dois
    porter cette derniére comme paramétres ?? si vous pouvez me le montrer a traver
    un petit code ça sera mieux .

    3- derniérement , si j'ai commande 1;commande2 | commande 3
    a ce moment , c'est la commande 2 qui vas communiquer avec la commande 3 ?
    et y a pas d'echange entre commande1 et commande 3 ?

    merci d'avance

  2. #2
    Membre expérimenté
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    slt tt le monde :

    j'ai quelques questions concernant les pipes :

    1- d'abord , quand j'ai 3 commandes par exemples qui s'executent en pipe :
    commande1 | commande2 | commande3
    je dois créer en premier un seul tube ( int tube[2] ) que je vais utiliser d'abord entre
    commande 1 et commande2 , puis entre commande 2 et commande 3 ,ou bien je
    dois créer pour chaque | un tube ?

    2- et quand je crée des processus aux quels je vais faire du recouvrement pour
    chacun d'eux ( si je remplace le programme de chaque processus par un
    executable d'une commande de linux) , exemple : mkdir rep1 | ls
    que dois passer la commande mkdir a la commande ls comme paramétre ?
    je pense que ça se réalise a l'aide de la fonction write mais comment ? et que dois
    porter cette derniére comme paramétres ?? si vous pouvez me le montrer a traver
    un petit code ça sera mieux .

    3- derniérement , si j'ai commande 1;commande2 | commande 3
    a ce moment , c'est la commande 2 qui vas communiquer avec la commande 3 ?
    et y a pas d'echange entre commande1 et commande 3 ?

    merci d'avance
    1 - il faut absolument 2 pipes car l'appel a read doit forcement être bloquant au niveau de la lecture du pipe vu que les deux processus sont executés "en meme temps"

    2 - mkdir rep1 | ls ?? as tu réélement compris ce qu'il se passait ? tu ne peux pas faire ca ! ls n'attend rien de STDIN (du clavier quoi...) et surtout mkdir n'ecris rien sur STDOUT (ecran) donc cette redirection ne sert strictement a rien...
    sinon la commande de gauche ne passe pas de paramètre à la commande de droite:
    imagine que la comande de droite va faire un appel a scanf (ou autre fonction de lecture du clavier) et bien scanf est grosso modo un write(STDIN...)
    la redirection consiste à remplacer STDIN par le coté d'un tube
    de meme pour la coammnde de gauche, printf correspond a un write(STDOUT...)
    dans ce cas la, la redirection consiste a remplacer STDOUT par l'autre bout du tube !

    3 - non pas de redirection entre commande1 et commande3

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 836
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    slt tt le monde :

    j'ai quelques questions concernant les pipes :

    1- d'abord , quand j'ai 3 commandes par exemples qui s'executent en pipe :
    commande1 | commande2 | commande3
    je dois créer en premier un seul tube ( int tube[2] ) que je vais utiliser d'abord entre
    commande 1 et commande2 , puis entre commande 2 et commande 3 ,ou bien je
    dois créer pour chaque | un tube ?

    2- et quand je crée des processus aux quels je vais faire du recouvrement pour
    chacun d'eux ( si je remplace le programme de chaque processus par un
    executable d'une commande de linux) , exemple : mkdir rep1 | ls
    que dois passer la commande mkdir a la commande ls comme paramétre ?
    je pense que ça se réalise a l'aide de la fonction write mais comment ? et que dois
    porter cette derniére comme paramétres ?? si vous pouvez me le montrer a traver
    un petit code ça sera mieux .

    3- derniérement , si j'ai commande 1;commande2 | commande 3
    a ce moment , c'est la commande 2 qui vas communiquer avec la commande 3 ?
    et y a pas d'echange entre commande1 et commande 3 ?

    merci d'avance
    Pour être très simple:
    1) toute commande qui écrit un truc à l'écran peut envoyer ce truc dans un pipe => commande | ... => exemple: ls -l
    2) toute commande qui attend un truc du clavier peut prendre ce truc d'un pipe => ... | commande
    Ainsi, le pipe permet d'envoyer le résultat (affiché par la commande 1) dans l'entrée de la commande 2 => ls -l | wc => tout ce qui est affiché par "ls -l" sera compté par "wc"

    Ce mécanisme permet d'emboiter des suites de commandes pour exécuter des actions précises mais complexes...

    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat /etc/passwd | sort | tr '[:lower:]' '[:upper:]' | sed -e "s/:/ /g" | awk '{printf("%s\n", $0); if ((NR % 5) == 0) printf("\n")}'
    1) le cat affiche le fichier
    2) le sort trie cet affichage
    3) le tr transforme toutes les minuscules en majuscules
    4) le sed convertis chaque ":" en espace
    5) le awk insère une ligne vide toute les 5 lignes
    Ce qui me produit en final un listing aéré du fichier "/etc/passwd"
    ...

    Bien entendu, envoyer mkdir dans un pipe est absurde. La commande mkdir n'affiche rien. De même envoyer un truc dans "ls" est aussi absurde, la commande "ls" n'attend rien du clavier...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre confirmé
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Par défaut
    re !!
    merci a vous tous , j'ai tres bien compris le principe des pipe , juste il reste une
    petite ambiguité, je viens de realiser un mini-shell qui traite les commandes en pipe,
    lorsque deux commandes en pipes qui sont tapé, disant : cat /etc/passwd | sort

    - d'abord je dois créer un tube ( int tube [2] ) ,
    - j' appelle la fonction pipe( tube ) , qui est de l'entête < unistd.h >
    - puis je crée deux processus a l'aide du fork()
    - le premier ferme le destripteur close ( tube[1] ), et le deuxiéme ouvre le le
    descripteur tube [0] par open( tube[0] );
    - mais la premier processus (celui de la commande cat )est ce que je lui fait un
    recouvrement ( c'est a dire je remplace son code par l'executable de la fonction cat)
    ou pas ??
    - ensuite que doit ecrire le processus de la commande cat dans le stdout a l'aide de la
    fonction write !!

    et si vous pouvez me le montrer avec un petit code ça sera encore mieux

    merci encore une fois

  5. #5
    Membre expérimenté
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Par défaut
    je t'ai deja donné un code qui le fait (avec les explications):
    http://www.developpez.net/forums/d72...availler-pipe/

  6. #6
    Membre confirmé
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Par défaut
    re
    pouvez vous me dire a quoi sert cette duplication pour les deux processus, ou il y a des etoiles *********
    en plus la fermeture des deux descripeteurs pfd[0] , et pfd[1] pourquoi elle est refaite deux fois @@@
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    main(void)
    {
          int pfd[2];
          if (pipe(pfd) == -1)
                syserr("pipe");
          switch (fork()) {
          case -1:
                syserr("fork");
          case 0:
                if (close(1) == -1)
                       syserr("close");
                if (dup(pfd[1]) != 1)  ******************
                       syserr("dup");
                if (close(pfd[0]) == -1 || close(pfd[1]) == -1)    @@@
                       syserr("close2");
                execlp("who","who",NULL);
                syserr("execl");
          }
          switch (fork()) {
          case -1:
                syserr("fork");
          case 0:
                if (close(0) == -1)
                       syserr("close3");
                if (dup(pfd[0]) != 0)
                       syserr("dup3");
                if (close(pfd[0]) == -1 || close(pfd[1]) == -1)   @@@
                       syserr("close4");
                execlp("wc","wc",NULL);
                syserr("execl2");
          }
          if (close(pfd[0]) == -1 || close(pfd[1]) == -1)
                syserr("close5");
          while (wait(NULL) != -1);
    }
    /*-----------------------------------------------------------------*/
    /*            Traitement des erreurs                               */
    /*-----------------------------------------------------------------*/
    syserr(char *s)
    {
          printf("erreur de la primitive ");
          printf("%s\n",s);
          exit(1);
    }


    oui je l'ai vu cette exemple , mais moi je veux generaliser ma fonction ,si j'ai plusieurs commandes en pipe disant N dont je ne connais pas le nombre exacte , comment faire a ce moment la ?? je pense pas que je peux utiliser un tableau de N descripteurs car déja la fontion pipe() ne le permet pas , mais est ce que je peux utiliser le tube ( int tube[2] )
    une fois entre commande1 | commande2 et puis commande 2 | commande 3 et ainsi de suite ??
    merci d'avance

  7. #7
    Membre expérimenté
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Par défaut
    dup duplique un desctipteur de fichier a la premiere position disponible dans la table des descripteurs de fichier

    dans notre cas la table contient:
    0,1,2,3,4
    ou 0 == stdin
    1 == stdout
    2 == stderr
    3 == pfd[0]
    4 == pfd[1]

    or on ferme 1
    on a donc:
    0,vide,2,3,4

    en appelant dup(pfd[1]) on copie le descrpteur pfd[1] a la premiere place dispo:
    on obtien alors:
    0,5,2,3,4

    pour plus de details:
    man 2 dup

    sinon pour ton autre question, apres un fork, il me semble que le compteur d'utilisation des descripteurs de fichier partagés sont incrémentés, il faut absolument que les deux fils ferment chaque descripteur pour que le compteur d'utilisation redevienne egal a 0 et ainsi libérer l'inode.
    je ne suis pas sur a 100% de ce dernier point, mais c'est grosso modo ca...

Discussions similaires

  1. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49
  2. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38
  3. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  4. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo