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 :

Variables et commandes simultanées


Sujet :

Shell et commandes GNU

  1. #1
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Variables et commandes simultanées
    Bonjour,

    Je débute en bash (je m'y suis mis il y a 15 jours).
    A partir d'un serveur, je veux lancer 2 commandes de calcul MD5 de tres gros fichiers sur 2 autres serveurs (en ssh) et récupérer ces MD5 dans des variables pour les comparer.
    Si les commandes s'executent en série, je n'ai pas de problème, mais dès que je veux paralleliser les commandes, je me retrouve avec des variables vides, et je n'arrive pas à m'en sortir (j'ai essayer des boucles, des wait etc.)

    ceci fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MD5FichierServeurA=$(ssh -l root ipserveurA "md5sum '$CheminFichierSurLeServeurA'")
    MD5FichierServeurB=$(ssh -l root ipserveurB "md5sum '$CheminFichierSurLeServeurB'")
    ceci ne fonctionne pas (la commande de calcul est bien envoyée à chaque serveur en simultanée, mais les variables MD5blabla restent deseperement vide:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    MD5FichierServeurA=$(ssh -l root ipserveurA "md5sum '$CheminFichierSurLeServeurA'")&
    MD5FichierServeurB=$(ssh -l root ipserveurB "md5sum '$CheminFichierSurLeServeurB'")&
    wait
    Certains fichiers pouvant demander pas loin 1/4h de calcul, le lancement en // me ferait gagner pas mal de temps.
    Si quelqu'un sait comment je peux m'en sortir...

  2. #2
    Expert éminent sénior
    Avatar de Escapetiger
    Homme Profil pro
    Administrateur système Unix - Linux
    Inscrit en
    Juillet 2012
    Messages
    1 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur système Unix - Linux

    Informations forums :
    Inscription : Juillet 2012
    Messages : 1 480
    Points : 11 091
    Points
    11 091
    Par défaut
    Citation Envoyé par largentula Voir le message
    ceci ne fonctionne pas (la commande de calcul est bien envoyée à chaque serveur en simultanée, mais les variables MD5blabla restent deseperement vide:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    MD5FichierServeurA=$(ssh -l root ipserveurA "md5sum '$CheminFichierSurLeServeurA'")&
    MD5FichierServeurB=$(ssh -l root ipserveurB "md5sum '$CheminFichierSurLeServeurB'")&
    wait
    Certains fichiers pouvant demander pas loin 1/4h de calcul, le lancement en // me ferait gagner pas mal de temps.
    Si quelqu'un sait comment je peux m'en sortir...
    Bonjour, je pencherai pour un problème de syntaxe à savoir, rajouter pour chaque variable un espace entre la dernière parenthèse et le "&" ou bien inclure le "&" avec un espace à l'intérieur de $(ssh ... & ) . Je ne peux pas tester ici.

    EDIT : troisième suggestion, faire un echo explicite de tes variables echo $MD5FichierServeurN avant le wait (pour "nettoyer" l'affichage du type [pid]+ Done )
    « Developpez.com est un groupe international de bénévoles dont la motivation est l'entraide au sens large » (incl. forums developpez.net)
    Club des professionnels en informatique

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Escapetiger Voir le message
    Bonjour, je pencherai pour un problème de syntaxe à savoir, rajouter pour chaque variable un espace entre la dernière parenthèse et le "&" ou bien inclure le "&" avec un espace à l'intérieur de $(ssh ... & ) . Je ne peux pas tester ici.
    Ben... je pense pas que ça puisse marcher comme ça
    Si tu fais A=$({ sleep 10; echo A; } &), l'instruction entière doit être terminée avant de rendre la main. Et ça dure bien 10 secondes!
    Impossible de paralléliser de cette manière.

    Pas trop le temps de regarder, mais je crois qu'il vaut mieux chercher du côté des exemples de fifo avec mkfifo.

    En gros, on ouvre 2 fifos sur lesquels on commence à lire en background.
    Et on lance les process en background qui vont écrire dedans...

  4. #4
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Je confirme que le & avant la ) ne fonctionne pas, les process sont lancés les uns à la suite des autres.
    l'espace après la ) et avant le & ne change rien non plus...
    mais merci tout même pour les suggestions.

    je vais donc regarder du coté fifo et mkfifo (que je ne connais pas du tout) en esperant ne pas être obligé de monter une usine à gaz (et que ce ne soit pas trop compliqué...)

  5. #5
    Expert éminent sénior
    Avatar de Escapetiger
    Homme Profil pro
    Administrateur système Unix - Linux
    Inscrit en
    Juillet 2012
    Messages
    1 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur système Unix - Linux

    Informations forums :
    Inscription : Juillet 2012
    Messages : 1 480
    Points : 11 091
    Points
    11 091
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Ben... je pense pas que ça puisse marcher comme ça
    Si tu fais A=$({ sleep 10; echo A; } &), l'instruction entière doit être terminée avant de rendre la main. Et ça dure bien 10 secondes!
    Impossible de paralléliser de cette manière.

    Pas trop le temps de regarder, mais je crois qu'il vaut mieux chercher du côté des exemples de fifo avec mkfifo.

    En gros, on ouvre 2 fifos sur lesquels on commence à lire en background.
    Et on lance les process en background qui vont écrire dedans...
    Merci jack-ft, effectivement; en poussant la logique de la fin de l'instruction entière, je me demande si A=$({ sleep 10; echo A; } &)& peut fonctionner ou ne fait que répéter "l'erreur".
    « Developpez.com est un groupe international de bénévoles dont la motivation est l'entraide au sens large » (incl. forums developpez.net)
    Club des professionnels en informatique

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Escapetiger Voir le message
    Merci jack-ft, effectivement; en poussant la logique de la fin de l'instruction entière, je me demande si A=$({ sleep 10; echo A; } &)& peut fonctionner ou ne fait que répéter "l'erreur".
    Ben... je vois pas comment on pourrait "affecter" une valeur à A en background ?!?!? et rendre la main aussitôt et récupérer la valeur affectée (quand?) alors que les instructions vont continuer à se dérouler alors que A ne serait pas encore valuée...
    ça peut vraiment pas marcher comme ça!

  7. #7
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    j'ai tenté le fifo comme indiqué par jack-ft :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
       mkfifo fifoA fifoB
       ssh -l root ipserveurA "md5sum '$cheminduFichierserveurA'" > fifoA &
     
       ssh -l root ipserveurB "md5sum '$cheminduFichierserveurB'" > fifoB &
     
       while test -z "$MD5fichierserveurA" && test -z "$MD5fichierserveurB"
       do
               read MD5fichierserveurA < fifoA
                read MD5fichierserveurB < fifoB
        done
        rm fifoA
        rm fifoB
    j'ai bien des resultats à la fin dans mes variables, mais seulement les ssh... "md5sum ..." ne s'executent pas en // mais l'un après l'autre... j'ai dû oublier quelque chose...

  8. #8
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par largentula Voir le message
    j'ai tenté le fifo comme indiqué par jack-ft :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
       mkfifo fifoA fifoB
       ssh -l root ipserveurA "md5sum '$cheminduFichierserveurA'" > fifoA &
       ssh -l root ipserveurB "md5sum '$cheminduFichierserveurB'" > fifoB &
     
       while test -z "$MD5fichierserveurA" && test -z "$MD5fichierserveurB"
       do
               read MD5fichierserveurA < fifoA
                read MD5fichierserveurB < fifoB
        done
        rm fifoA
        rm fifoB
    ça me paraît bien... mais je ne suis pas un grand spécialiste...

    j'ai bien des resultats à la fin dans mes variables, mais seulement les ssh... "md5sum ..." ne s'executent pas en // mais l'un après l'autre... j'ai dû oublier quelque chose...
    D'après le code, les commandes devraient bien s'exécuter en parallèle.
    Comment détermines-tu que les commandes s'exécutent en série et non en parallèle?
    Tu regardes les process, les traces, autre chose?

  9. #9
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    je jette un oeil sur les process en cours sur les serveurs A et B (avec "top") et comme certain de mes fichiers sont gros, j'ai largement le temps de voir si md5sum tourne en // ou non...

    j'arrive à faire tourner en // en ajoutant quelques parenthèse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ( ssh -l root ipserveurA "md5sum '$cheminduFichierserveurA'" ) & > fifoA &
    ( ssh -l root ipserveurB "md5sum '$cheminduFichierserveurB'" ) & > fifoB &
    mais le résultat est du genre :
    resultatdumd5 /chemin/nondufichier (ce qui n'est pas génant) mais la boucle refuse de se finir...
    grace à ton aide, j'approche du but, mais pour l'instant j'ai l'impression de tourner autour...

  10. #10
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par largentula Voir le message
    je jette un oeil sur les process en cours sur les serveurs A et B (avec "top") et comme certain de mes fichiers sont gros, j'ai largement le temps de voir si md5sum tourne en // ou non...

    j'arrive à faire tourner en // en ajoutant quelques parenthèse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ( ssh -l root ipserveurA "md5sum '$cheminduFichierserveurA'" ) & > fifoA &
    ( ssh -l root ipserveurB "md5sum '$cheminduFichierserveurB'" ) & > fifoB &
    Mouais... un peu beaucoup de perluettes... à mon goût...

    mais le résultat est du genre :
    resultatdumd5 /chemin/nondufichier (ce qui n'est pas génant) mais la boucle refuse de se finir...
    grace à ton aide, j'approche du but, mais pour l'instant j'ai l'impression de tourner autour...
    Je crois me souvenir qu'il faut se mettre en attente de fin des process (avec wait, peut-être? (ou vérifier qu'ils continuent à tourner avec ps?)) dont on peut trouver le pid avec "$!":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ sleep 30 &
    [1] 61228
     
    $ echo $!
    61228
     
    $ jobs
    [1]+  Running                 sleep 30 &
     
    $ ps -ef | fgrep 61228
     jack      61228    4828 pty1     14:16:33 /usr/bin/sleep

  11. #11
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    à force de tester plein de chose, j'ai décidé de faire 2 fonctions pour calculer les MD5 A et B :
    (je suis d'accord qu'il y a beaucoup de '&' mais si j'en retire ça fonctionne encore moins bien...)

    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
     
    CalMD5RingA ()
    {
    echo debut fonction calmd5A
            rm -f fifoA
            mkfifo fifoA
            ssh -l root 10.185.151.3 "md5sum '$FichierRingA'" > fifoA &
            read MD5RingA < fifoA
            rm -f fifoA
            export MD5RingA
            echo RA : $MD5RingA
    echo fin fonction calmd5A
    }
     
    CalMD5RingB ()
    {
    echo debut fonction calmd5B
            rm -f fifoB
            mkfifo fifoB
            ssh -l root 10.185.151.53 "md5sum '$FichierRingB'" > fifoB &
            read MD5RingB < fifoB
            rm -f fifoB
            export MD5RingB
            echo RB : $MD5RingB
    echo fin fonction calmd5B
    A ce niveau, mes variables MD5RingA et B ont les bonnes valeurs.


    ces fonctions sont ensuite appellée ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     CalMD5RingA &
     CalMD5RingB &
     wait
    echo MD5_A : $MD5RingA et MD5_B : $MD5RingB
    mais malgré ma tentative d'export des variables MD5RingA et B, elles se retrouvent vides en sortie de fonction...

  12. #12
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par largentula Voir le message

    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
    CalMD5RingA ()
    {
    echo debut fonction calmd5A
            rm -f fifoA
            mkfifo fifoA
            ssh -l root 10.185.151.3 "md5sum '$FichierRingA'" > fifoA &
            read MD5RingA < fifoA
            rm -f fifoA
            export MD5RingA
            echo RA : $MD5RingA
    echo fin fonction calmd5A
    }
    
    CalMD5RingB ()
    {
    echo debut fonction calmd5B
            rm -f fifoB
            mkfifo fifoB
            ssh -l root 10.185.151.53 "md5sum '$FichierRingB'" > fifoB &
            read MD5RingB < fifoB
            rm -f fifoB
            export MD5RingB
            echo RB : $MD5RingB
    echo fin fonction calmd5B
    A ce niveau, mes variables MD5RingA et B ont les bonnes valeurs.


    ces fonctions sont ensuite appellée ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     CalMD5RingA &
     CalMD5RingB &
     wait
    echo MD5_A : $MD5RingA et MD5_B : $MD5RingB
    mais malgré ma tentative d'export des variables MD5RingA et B, elles se retrouvent vides en sortie de fonction...
    Erreur classique!

    Un export sert uniquement à envoyer la variable (et sa valeur) vers les fonctions ou process appelés depuis l'endroit qui déclare et non vers l'appelant de la fonction déclarante.

    Comme tu n'as aucun "typeset" ou "let", toutes tes variables sont globales, donc connues dans tout le programme.

    Conclusion: le export ne sert à rien. Tu auras le même résultat si tu l'enlèves.

    Il faut conditionner la lecture dans le fifo à la fin du process. Je ne sais plus comment on fait (cherche des exemples de mkfifo sur ce forum ou sur le net).

    Pseudo-code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            mkfifo fifoB
            ssh -l root 10.185.151.53 "md5sum '$FichierRingB'" > fifoB &
            psB=$!
            attendre fin de psB puis lire fifo
            read MD5RingB < fifoB
    à vérifier et coder...

  13. #13
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Erreur classique!
    je débute

    Citation Envoyé par jack-ft Voir le message
    Conclusion: le export ne sert à rien. Tu auras le même résultat si tu l'enlèves.
    je confirme mais par la logique inverse : j'ai le même résultat depuis que je l'ai mis...

    Citation Envoyé par jack-ft Voir le message
    Il faut conditionner la lecture dans le fifo à la fin du process. Je ne sais plus comment on fait (cherche des exemples de mkfifo sur ce forum ou sur le net).

    Pseudo-code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            mkfifo fifoB
            ssh -l root 10.185.151.53 "md5sum '$FichierRingB'" > fifoB &
            psB=$!
            attendre fin de psB puis lire fifo
            read MD5RingB < fifoB
    à vérifier et coder...
    Je ne comprends pas l'interet d'attendre la fin de psB (je ne comprend pas psB tout court), ma variable à déjà a bonne valeur en fin de fonction. C'est une fois que je quite la fonction qu'elle perd sa valeur.

  14. #14
    Expert éminent sénior
    Avatar de Escapetiger
    Homme Profil pro
    Administrateur système Unix - Linux
    Inscrit en
    Juillet 2012
    Messages
    1 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur système Unix - Linux

    Informations forums :
    Inscription : Juillet 2012
    Messages : 1 480
    Points : 11 091
    Points
    11 091
    Par défaut Errare humanum est, perseverare diabolicum
    Citation Envoyé par largentula Voir le message
    je débute


    je confirme mais par la logique inverse : j'ai le même résultat depuis que je l'ai mis...


    Je ne comprends pas l'interet d'attendre la fin de psB (je ne comprend pas psB tout court), ma variable à déjà a bonne valeur en fin de fonction. C'est une fois que je quite la fonction qu'elle perd sa valeur.
    Au delà de mes premières suggestions vraiment mal exprimées dans lesquelles je me suis fourvoyé comme l'a justement stipulé jack-ft, je propose un nouveau test que je viens de réaliser en local (il ne simule pas la partie ssh -l), avec succès, qui revient sur tes essais initiaux (sans mkfifo et sans appel de fonction, pour conserver l'environnement initial)

    En fait, je rebondis sur les préconisations de jack-ft pour la partie wait du pid donné (je pense effectivement que l'on perd le contenu des variables suite aux fermetures des "file descriptor")

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    root@slitaz:~$ cat test.sh
    #/bin/bash
    #set -xv
    varA=$(sleep 40 ; find /home | wc -l &)
    wait $! &
    varB=$(sleep 30 ; find /var | wc -l &)
    wait $! & 
    varC=$(sleep 10 ; find / | wc -l &)
    echo  varA $varA varB $varB varC $varC
    ##wait 
    ##echo apres wait varA $varA
    ##echo apres wait varB $varB
    root@slitaz:~$ ./test.sh 
    varA 1193 varB 1900 varC 49826
    Nota: j'ai rajouté une troisième variable intentionnellement; ici ça fonctionne, j'espère qu'après ajustements ce sera le cas dans ta configuration.

    Nota bis: pas facile par écrit dans un topic, j'espère avoir été clair à la manière d'un Hubert Reeves quand il parle d'astrophysique (bon OK ! je n'ai pas son niveau de chercheur ni son charisme )

    EDIT : ça ne fonctionne pas en fait, il n'y a qu'un pas voire deux (trois ici) entre la ténacité et l'entêtement.
    « Developpez.com est un groupe international de bénévoles dont la motivation est l'entraide au sens large » (incl. forums developpez.net)
    Club des professionnels en informatique

  15. #15
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2014
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    La seul solution que j'ai trouvée pour récupérer la valeur de la variable de la fonction, c'est de passer par un fichier externe :

    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
     
    CalMD5RingA ()
    {
            rm -f fifoA
            mkfifo fifoA
            ssh -l root 10.185.151.3 "md5sum '$FichierRingA'" > fifoA &
            read MD5RingAtmp < fifoA
            echo $MD5RingAtmp > md5tmpA
            rm -f fifoA
    }
     
    CalMD5RingB ()
    {
            rm -f fifoB
            mkfifo fifoB
            ssh -l root 10.185.151.53 "md5sum '$FichierRingB'" > fifoB &
            read MD5RingBtmp < fifoB
            echo $MD5RingBtmp > md5tmpB
            rm -f fifoB
    }
    puis en appel et récuperation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CalMD5RingA &
    CalMD5RingB &
    wait
    MD5RingA=`cat md5tmpA`
    MD5RingB=`cat md5tmpB`
     
    ...
     
    rm -f md5tmpA
    rm -f md5tmpB
    Maintenant, faut que je voie comment utiliser les fichiers temporaires...
    En tout cas, merci de votre aide et du temps que vous avez consacré à mon problème.

    Edit : je clos le sujet, mais je suis toujours preneur d'une solution "plus propre" si quelqu'un a ça dans sa besace...

  16. #16
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    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 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par largentula Voir le message
    Maintenant, faut que je voie comment utiliser les fichiers temporaires...
    En tout cas, merci de votre aide et du temps que vous avez consacré à mon problème.

    Edit : je clos le sujet, mais je suis toujours preneur d'une solution "plus propre" si quelqu'un a ça dans sa besace...
    Hmm j'ai quelque chose qui ressemble au début du commencement d'une ébauche d'une éventualité de possibilité...

    Après un petit coup de "man bash" et quelques "/ wait", je suis tombé sur la commande "coproc" qui m'a inspiré le petit script suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash
     
    coproc cpa { sleep 10; echo 'a'; }
    coproc cpb { sleep 15; echo 'b'; }
     
    outA=$(cat <&"${cpa[0]}")
    outB=$(cat <&"${cpb[0]}")
     
    echo "${outA} ${outB}"
    Qui s'exécute bien en 15 secondes (le max(10, 15)):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ./coproc.sh: line 4: warning: execute_coproc: coproc [7972:cpa] still exists
    a b
     
    real    0m15.134s
    user    0m0.030s
    sys     0m0.136s
    Par contre, je ne sais pas ce que veut dire le warning...
    et, surtout, beaucoup plus grave, le script produit une erreur car il n'arrive pas à lire la 2ème réponse si elle finit avant la 1ère ?!?!?!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ time ./coproc.sh
    ./coproc.sh: line 4: warning: execute_coproc: coproc [7704:cpa] still exists
    ./coproc.sh: line 7: "${cpb[0]}": Bad file descriptor
    a
     
    real    0m15.098s
    user    0m0.030s
    sys     0m0.060s

  17. #17
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 295
    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 295
    Points : 12 772
    Points
    12 772
    Par défaut
    Bonjour,

    En fait, le fait de passer des commandes en background, c'est le même que le problème que de "piper" une commande, on crée un sous-shell, et donc pas d'héritage de variables...
    On est donc bien obligé de passer par un fichier.
    Par contre, sous linux, on peut créer les fichiers directement en mémoire partagée, dont voici un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ TOTO="/dev/shm/t_var1"
    $ sleep 5 && echo titi >$TOTO &
    [1] 19399
    $ wait
    [1]+  Fini                    sleep 5 && echo titi > $TOTO
    $ TOTO=$(<$TOTO)
    $ echo $TOTO
    titi
    $ cat /dev/shm/t_var1 
    titi
    $ rm /dev/shm/t_var1
    Après, à savoir la méthode la plus propre...
    Cordialement.

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

Discussions similaires

  1. [Variables] Concaténation commande AWK
    Par amazigh42 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 27/04/2015, 11h06
  2. Variable pour commande dans script en vrac après 1re utilisation
    Par Jipété dans le forum Shell et commandes GNU
    Réponses: 10
    Dernier message: 09/01/2014, 00h57
  3. [PowerShell] passer variable dans commande
    Par sacan dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 31/12/2012, 16h27
  4. Comment réaliser des commandes simultanément ?
    Par winnie82 dans le forum Langage
    Réponses: 5
    Dernier message: 18/08/2006, 14h04
  5. Réponses: 2
    Dernier message: 23/03/2004, 11h24

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