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

Shell et commandes GNU Discussion :

Named pipe bidirectionnel


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 31
    Par défaut Named pipe bidirectionnel
    Bonjour à tous & à toutes,

    Je me suis lancé dans un projet de scripting Bash pour apprendre à utiliser les Named Pipe.

    Ecrire & lire dans un Named Pipe (FIFO) ne me pose pas de problème. Mais la "double" communication, elle, si.

    En fait, j'aimerai que mes scripts fassent ceci:
    1er script:
    --------------------------------------------------------------------------
    demon
    Il comportera un nombre à deviner.

    2ème script
    client
    Il fera des propositions au demon afin de trouver le nombre qu'il contient.
    --------------------------------------------------------------------------

    Le démon répondra "le nombre est > à ce que vous avez proposé" (ou < ou = -> si égal bingo le script client s'arrête, mais pas le demon)


    Au niveau de l'affichage, cela se représente comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ ./demon
    Vous avez essayé le nombre 10
    Vous avez essayé le nombre 15
    Vous avez essayé le nombre 12
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ ./client
    Votre proposition:
    10
    10 n'est pas le bon nombre, c'est > au nombre à trouver
    Votre proposition:
    15
    15 n'est pas le bon nombre, c'est < au nombre à trouver
    Votre proposition:
    12
    Bingo!
    // on sort du script
    $

    La génération du nombre dans le demon ne doit pas être prise en compte. Tout ce qui est switch pour retourner le < > ou = ne me pose pas de problème.

    J'arrive à faire la lecture quand on fait la proposition, et donc l'affichage de demon, mais par contre je n'arrive pas à renvoyer une valeur à mon client, et donc savoir si on a trouvé ou non...

    Mes script en sont là pour les NamedPipe:
    demon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/bin/bash
    MYVAR="10"
    while read f ; do
            echo "valeur" $f 
    done < tube1


    client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/bin/bash
    while :
    do
            cat > tube1
    done

    Je voulais faire en sorte que dans mon script demon, je fasse un genre de "echo $result > tube2" et donc de faire un cat < tube2 dans mon client, mais cela ne fonctionne pas...

    Je ne suis pas sûre d'être sur la bonne voix...

    Si quelqu'un pouvait éclairer ma lanterne, ca serait vraiment sympa!

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 297
    Par défaut
    Bonjour

    Tu es en train de fabriquer une route unique sur laquelle les voitures circulent dans les deux sens. Si tu n'as pas de collision, tu as vraiment de la chance. Il faut créer d'autres routes, de ton serveur vers tes clients.

    Vois ça comme des boîtes aux lettres. Tout script voulant recevoir du courrier doit avoir son pipe nommé. Il te faut gérer côté serveur un tableau des pipes de tes clients.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 31
    Par défaut
    L'idée finale étant bien de pouvoir poser la question depuis plusieurs terminaux au script demon.

    Au niveau de la conception, peux-tu m'éclairer un peu?

  4. #4
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 297
    Par défaut
    Je ne vois pas ce qui n'est pas clair.

    Chacun sa boîte au lettres, chacun son tube. Il faut éviter les blocages. De la même façon qu'on ne s'occupe plus d'une lettre, une fois qu'on l'a envoyée, il faut mettre la tâche qui écrit dans le tube en tâche de fond.

    exemple:Le message est bien envoyé mais la commande n'est pas bloquante.

    La réception des messages, elle, peut être bloquante:
    Cela implique de vérifier régulièrement si le processus n'a pas du courrier.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 31
    Par défaut
    C'est au niveau code que j'ai du mal de conceptualiser la gestion du pipe

    demon
    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
     
    find="12"
    while read f ; do
        echo "Valeur testée" $f &
     
        if [ $f -lt $find ] ; then
           msg="Le nombre a trouver est >"
        elif [ $f -gt $find ] ; then
           msg="Le nombre a trouver est <"
        else 
           msg="Bingo"
        fi   
        cat > tube2
        echo $msg
    done < tube1
    Et le client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    cat < tube2 &
    while [ $msg -n ] 
    do
            cat > tube1
            echo "insérez une valeur"
    done
    Ca en est là +/- dans ma conceptualisation de la chose...

    P.S: Déjà merci pour ton temps!

  6. #6
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 297
    Par défaut
    Cette commande n'est pas bonne:"cat" sert à afficher. Afficher quoi ? Tu ne le dis pas. Si la commande bloque, c'est parce qu'il attend que tu lui dises.

    De plus, Je t'ai dit qu'il ne fallait pas que les messages envoyés soient bloquants. Il faut donc rajouter un '&' en fin de ligne pour que le processus s'exécute en fond. Sinon, il monopolise la main.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 31
    Par défaut
    Juste, erreur de ma part.

    Ca avance, maintenant je sais renvoyer vers le tube2, mais la lecture de ce que j'écris de dans, je n'arrive pas à le lire dans le script client, j'ai testé en bouclant sur ce même pipe, mais ca bloque. j'ai essayé avec les & mais c'est peu concluant.

    demon
    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
     
    #!/bin/bash
    find="12"
    while read f ; do
        echo "Valeur testée" $f
     
        if [ "$f" -lt "$find" ] ; then
           msg="Le nombre a trouver est >"
        elif [ "$f" -gt "$find" ] ; then
           msg="Le nombre a trouver est <"
        else
           msg="Bingo"
        fi
        echo $msg > tube2 &
     
    done < tube1
    client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #!/bin/bash
    msg=$((tail -n 1 < tube2 )) # ou quelque chose comme ça....
    while [ $msg -n ] 
    do
            cat > tube1
            echo "insérez une valeur"
    done
    ~                                                                             
    ~

  8. #8
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 297
    Par défaut
    $(( )) est l'opérateur arithmétique. Il sert à faire du calcul:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     nombre=13;echo $((nombre + 1))
    14
    Ne pas confondre avec $( )

    Pour afficher le contenu d'un tube,
    suffit

    Pour mettre le contenu d'un tube dans une variable,
    suffit

  9. #9
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 376
    Par défaut
    Bonjour,

    En principe les pipes nommés, on les fait avec mkfifo et ensuite on fait les redirections en conséquences.
    Comme je ne vois pas de création de ceux-ci, je suppose qu'ils ont été créés en amont

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 31
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Bonjour,

    En principe les pipes nommés, on les fait avec mkfifo et ensuite on fait les redirections en conséquences.
    Comme je ne vois pas de création de ceux-ci, je suppose qu'ils ont été créés en amont
    Oui, c'est créé en amont, je me focalise sur la communication pour le moment.

    Je pense que mon erreur vient de ma boucle.

    Le cheminement entre l'affichage de mon tube2 et l'insertion de mon tube1 n'est pas bonne, et donc ma boucle ne l'est pas non plus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #!/bin/bash
    var="1"
     
    while [ $var -ne "0" ] 
    do
            cat > tube1 # j'ai tenté avec le &, mais bug aussi
            echo "insérez une valeur"
            msg=$(head -n 1 tube2)
            echo $msg
            if [ $msg -eq "Bingo" ] ; then
                 var="0"
            fi
    done
    Pour moi, ca serait un cheminement logique, mais apparemment non.

    J'ai essayé avec la mise en fond (via "&"), mais ca ne m'a pas avancé...

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 376
    Par défaut
    je pense que ce que tu veux faire c'est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    echo "Inserer une valeur:"
    read valeur
    echo $valeur > tube1
    A mettre à la place de ton:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cat >tube1
    echo "inserez une valeur:"
    Comme te l'a déjà expliqué, cat sert à concaténer le contenu d'un ou plusieurs fichiers dans un autre fichier et ses fichiers sont par défaut les entrées et sortie standard. Cela ne sert pas à faire de l'interactif.

  12. #12
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Contenu répertoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ ls
    client.sh  le_tube  serv.sh
    Le daemon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ cat serv.sh 
    #!/bin/bash
     
    exec <le_tube
     
    while read ligne
    do
    	echo "=> ${ligne}"
    done
    Le client :
    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
    $ cat client.sh 
    #!/bin/bash
     
    exec >le_tube
     
    while :
    do
    	echo "Insérez une valeur : "
    	read f
    	if [ ${f} -lt 12 ]
    	then
    		echo "Le nombre à trouver est > "
    	elif [ ${f} -gt 12 ]
    	then
    		echo "Le nombre à trouver est < "
    	else
    		echo "Bingo"
    		exit
    	fi
    done
    Lancement daemon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ ./serv.sh&
    [1] 19116
    Exécution client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ ./client.sh 
    => Insérez une valeur :
    10
    => Le nombre à trouver est >
    => Insérez une valeur :
    13
    => Le nombre à trouver est <
    => Insérez une valeur :
    12
    => Bingo
    [1]+  Fini                    ./serv.sh
     
    $

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 31
    Par défaut
    Merci à tous, le mixe de vos réponses m'ont permis d'avoir totalement ce que je voulais.


    Un grand merci à tous.

  14. #14
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par haNjo Voir le message
    L'idée finale étant bien de pouvoir poser la question depuis plusieurs terminaux au script demon.

    Au niveau de la conception, peux-tu m'éclairer un peu?
    Au risque de passer pour un chipoteur (ce qui m'étonnerait quand même), si plusieurs clients peuvent poser SIMULTANÉMENT des questions au script démon et si tu veux gérer une synchronicité rigoureuse, il ne faut pas que les clients utilisent le même pipe de retour!!!
    Sinon, il existe un risque (certes faible! (mais quand même...)) que le client A reçoive la réponse destinée au client B et réciproquement.

    Comme l'a dit Flodelarab, chaque client devrait avoir sa propre boîte à lettres.

    Du coup, comme le serveur ne peut pas deviner quelle est la boîte à lettres du client qui l'interroge, il faudrait que le client communique au serveur le nom de sa boîte à lettres.
    En gros, le client pourrait envoyer sur le tube du serveur un message contenant "<nombre> <nom_de_tube>" dont le sens serait quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "Le nombre <nombre> est-il le bon? Merci de me répondre sur le tube nommé <nom_de_tube>"
    Lorsque le serveur reçoit un message, il en extrait la partie <nombre> et la partie <nom_de_tube>, compare avec le nombre à deviner et retourne le résultat sur le tube indiqué.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Aide] Named Pipes sous windows
    Par azalsup dans le forum Visual C++
    Réponses: 3
    Dernier message: 28/01/2008, 16h39
  2. Tubes nommés (named pipes) asynchrones
    Par piziwate dans le forum C
    Réponses: 8
    Dernier message: 18/12/2007, 19h41
  3. Named Pipes - event
    Par Brosske dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 09/11/2007, 11h26
  4. Named Pipes sur vista
    Par Tosh dans le forum C++
    Réponses: 1
    Dernier message: 18/07/2007, 21h28
  5. Create named pipe
    Par albanovisch dans le forum C++
    Réponses: 3
    Dernier message: 06/07/2007, 09h07

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