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 locales, variables globales


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut variables locales, variables globales
    Bonjour, j'ai cette ligne en shell sur freeBSD:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n "/CUNIT_RUN_SUMMARY/,$"p ${curent} | while read ligne; do
    dans la boucle j'utilise des variables, qui ne sont plus visibles une fois en dehors de la boucle, il semblerait que ce soit à cause du pipe, mes variables ne sont visibles que dans le while qui est un nouveau processus.
    N'y à-t-il pas un moyen de récupérer mes variables hors du while ?
    (j'ai essayer export, ou faire des set avant le while, mais ça ne fonctionne pas mieux)

    Merci

  2. #2
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    tu veux pas mettre plus d'infos ? plus de détails sur ton script ?

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut
    En résumé, ça donne quelque chose comme ça (d'abord quelques infos):
    "liste contient" le resultat de qq ls ect, en gros, une liste sur des fichiers xml.
    "nom_balise" et le nom de la balise de la ligne courante du fichier xml
    "valeur" est la valeur contenu dans les balises xml.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    for curent in $liste; do
        sed -n "/CUNIT_RUN_SUMMARY/,$"p ${curent} | while read ligne; do
     
            # xml balise name
    	nom_balise=`echo "$ligne" | sed 's#>.*##;s#<##'`
    	# xml balise value
    	valeur=`echo "$ligne" | sed 's#</.*##;s#.*>##' | sed 's#\ ##g'`
            ...
            run_suites=$valeur 
        done
    done
     
    echo "$run_suites"
    voila par exemple ce que je voudrais pouvoir faire.
    (bien entendu je ne fais pas juste un echo de la variables tel quel, et je ne peux pas le faire à l'intérieur de la boucle while)

  4. #4
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Y'a peut-être moyen de ne pas utiliser le pipe...

    Exemple :
    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
    > cat whiletest2
    #!/bin/sh
    VAR=foo
    
    cat $0 | while read VAR2; do
       VAR=bar
    done
    
    echo $VAR
    > cat whiletest
    #!/bin/sh
    VAR=foo
    
    while read VAR2; do
       VAR=bar
    done < $0
    
    echo $VAR
    > ./whiletest2
    foo
    > ./whiletest
    bar
    >
    Mais il faudrait mettre le résultat du sed dans un fichier temporaire je ne sais pas si ça te conviendra...

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut
    J'y avais pensé, mais je préfère eviter.
    Enfin si je dis ça c'est uniquement par soucis de perf, mais je sais pas du tout en shell si c'est vraiment plus lourd d'écrire et lire dans un fichier temp (sachant que le resultat du sed doit faire plus ou moins 30 lignes à chaques fois)

  6. #6
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Ou alors évite le while read qui suxe mégadur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    OFS="${IFS}"
    IFS='
    '
    for ligne in $(sed -n "/CUNIT_RUN_SUMMARY/,$"p ${curent}); do
        etc...
    done
    IFS="${OFS}"
    [EDIT] Je dis ça je dis rien mais current prend deux « r »

  7. #7
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Sinon ça ce serait mieux non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for curent in $liste; do
    	nom_balise=$(sed '/CUNIT_RUN_SUMMARY/s#>.*##;s#<##' "${curent}")
    	# xml balise value
    	valeur=$(sed '/CUNIT_RUN_SUMMARY/s#</.*##;s#.*>##' | sed 's#\ ##g' "${curent}")
            ...
            run_suites=$valeur 
            echo "$run_suites"
    done
    J'ai pas vraiment testé (un petit peu, ça semble faire ce que tu veux a priori).

  8. #8
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    Côté perf, ça devrait pas poser de problème.

    En supposant que ton code est plus intéressant que ton exemple qui écrase à chaque ligne la variable $run_suites (à moins que cela ne soit le week-end qui arrive qui me fatigue ), et que tu ne peux donc pas trop modifier sa structure, est-ce que tu ne pourrais pas t'en sortir en regroupant tes commandes ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ cat whiletest2
    #!/bin/sh
    VAR=foo
    
    cat $0 | ( while read VAR2; do
       VAR=bar
    done
    
    echo $VAR
    )
    $ ./whiletest2
    bar

  9. #9
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    Bonjour,

    en ne fait, pour l'instant, que supposer que tu n'utilises pas BASH, est-ce vrai ?
    alors, pourquoi pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var=$(echo "foo bar
    bla baz" | while read a b; do echo "$a"; done)
    echo "$var"
    foo
    bla
    sinon, la commande sed n'est pas nécessaire.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    évites de faire aussi ... mais ça c'est juste pour optimiser les perfs....
    sed sait gérer les commandes multiples .... en séquence forcément mais même sur résultat d'une commande sed précédente....

    et enfin ne fais pas un mais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while..... done < fichier
    ou un

  11. #11
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Citation Envoyé par Alek-C Voir le message
    Côté perf, ça devrait pas poser de problème.

    En supposant que ton code est plus intéressant que ton exemple qui écrase à chaque ligne la variable $run_suites (à moins que cela ne soit le week-end qui arrive qui me fatigue ), et que tu ne peux donc pas trop modifier sa structure, est-ce que tu ne pourrais pas t'en sortir en regroupant tes commandes ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ cat whiletest2
    #!/bin/sh
    VAR=foo
    
    cat $0 | ( while read VAR2; do
       VAR=bar
    done
    
    echo $VAR
    )
    $ ./whiletest2
    bar
    Sympa l'astuce j'aurais pas pensé, merci.

    BSD y'a bash ou pas ? je connais pas du tout personnellement...



    Et bon c'est pas pour en rajouter hein ^^ mais :

    Citation Envoyé par boris_couturier Voir le message
    "liste" contient le resultat de qq ls ect,
    Citation Envoyé par boris_couturier Voir le message
    for current in $liste; do ...
    En gros ça nous donne un beau for in $(ls)... aie !

    Y'a un problème conceptuel là.

  12. #12
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut
    En supposant que ton code est plus intéressant que ton exemple qui écrase à chaque ligne la variable $run_suites (à moins que cela ne soit le week-end qui arrive qui me fatigue ), et que tu ne peux donc pas trop modifier sa structure, est-ce que tu ne pourrais pas t'en sortir en regroupant tes commandes ?
    Oui je te rassure, cette variable ne sera définie qu'une seule fois et je n'en ai plus besoin hors du while, par contre je fais aussi un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let "total_suites=$total_suites+$run_suites"
    et j'ai besoin de total_suites hors du wihle.

    Ou alors évite le while read qui suxe mégadur :

    for ligne in $(sed -n "/CUNIT_RUN_SUMMARY/,$"p ${curent}); do
    etc...
    done

    [EDIT] Je dis ça je dis rien mais current prend deux « r »
    en effet current prend 2 r...
    et j'ai déjà fait quelque chose comme ça au début, mais le xml est structuré comme ça: <BALISE> valeur </BALISE> et le for me fait 3 lignes là dessus, car il sépare sur les espaces.

    Sympa l'astuce j'aurais pas pensé, merci.

    BSD y'a bash ou pas ? je connais pas du tout personnellement...
    oui, il y a moyen de l'avoir avec quelque chose comme ça me semble: #!/usr/local/bin/bash

    frp31, pourquoi il est mieux d’éviter le ... | while ?
    (et je pars sur un while ... done < fichier, mais je voulais juste éviter le fichier temporaire, mais tant pis.)

  13. #13
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut
    Citation Envoyé par FRUiT Voir le message
    Et bon c'est pas pour en rajouter hein ^^ mais :




    En gros ça nous donne un beau for in $(ls)... aie !

    Y'a un problème conceptuel là.
    Ah bon ? x) je suis pas expert du tout en shell, pourquoi ça ne va pas ?

  14. #14
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Citation Envoyé par boris_couturier Voir le message
    et j'ai deja fait quelque chose comme ça au debut, mais le xml est structuré comme ça: <BALISE> valeur </BALISE> et le for me fait 3 lignes la dessus, car il sépare sur les espaces.
    Ben oui mais je change l'IFS exprès pour ça, pour découper selon les sauts de ligne et non les espaces. Tu devrais essayer...

    Cela dit ça reste du bricolage.


    Citation Envoyé par boris_couturier Voir le message
    Ah bon ? x) je suis pas expert du tout en shell, pk ça va pas ?
    Parce que ls ne donne pas une liste de fichiers, mais une représentation textuelle de noms de fichiers. Je cherche le blog qui en parle je trouve plus...

  15. #15
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut
    Ok, bon à savoir, c'est vrai qu'en y pensant, ls ne fait qu'afficher des noms.
    Mais ça existe en shell des variables autres que textuelles ? x)

    Sinon avec le IFS, ça fonctionne bien (je l'avais juste un peu mal placé, mais maintenant c'est bon) j'ai plus mon pipe, et j'ai plus mon while qui sux (ça je sais pas non plus pourquoi d'ailleurs)

    Merci pour les réponses
    (j'ai essayé ta méthode Alex, c'est une bonne idée, mais dans mon cas, je pense pas pouvoir l'utiliser, mon while se trouvait dans un for, et j'avais besoin de mes variables hors de ce for)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for....
        ... | ( while
            ...
        done
        ...
        )
    done
     
    # j'ai besoin de mes variables ici
    Je sais pas du tout si il est possible de mettre en parenthèse le for, juste comme ça, ,si ça l'est ça aurait fonctionné dans mon cas aussi ^

  16. #16
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    J'ai retrouvé le lien qui explique pourquoi ne pas parser ls :

    http://mywiki.wooledge.org/ParsingLs

    Et aussi une page très intéressante :

    http://mywiki.wooledge.org/BashPitfalls

    (lire notamment le premier chapitre)

  17. #17
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    A mon avis, tu devrais pouvoir simplifier ton script...

    Je ne dirais pas que mon idée est bonne; c'est juste bon à savoir et ça peut permettre de dépanner, mais ça n'est pas super propre (c'est d'ailleurs la seule de la page à avoir un vote négatif , dommage que je ne sache pas pourquoi).

    A mon avis, je pense que tu as plutôt soit un problème d'organisation de ton script, soit tu ne devrais pas utiliser le shell qui est peut être trop limité pour ce que tu cherches à faire ?

  18. #18
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    Citation Envoyé par FRUiT Voir le message
    J'ai retrouvé le lien qui explique pourquoi ne pas parser ls :

    http://mywiki.wooledge.org/ParsingLs

    Et aussi une page très intéressante :

    http://mywiki.wooledge.org/BashPitfalls

    (lire notamment le premier chapitre)
    Génial ce site
    Pour info :
    http://mywiki.wooledge.org/BashFAQ/024
    Ca ressemble vachement au problème

  19. #19
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 21
    Par défaut
    Perso, je trouve le shell de base pas super propre, vu ce qu'on peut faire avec, Mais (je le répète encore) je m'y connais pas assez pour affirmer ça.

    Sinon, je l'ai déjà simplifié par rapport à avant (où j'avais 2 boucles for quasi identiques à part que la liste des fichiers était dans un dossier différent...)

    En gros ce que ce script fait, il cherche dans 2 répertoires (et dans des sous-répertoires, ect...) des fichiers avec une extension .xml, puis quand il à la liste, il lit chaque fichier xml à partir d'une certaine ligne pour piocher des infos particulières, et à la fin générer un .xml global résumant les infos de tous les fichiers xml trouvés.

  20. #20
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    pour le traitement de fichiers XML, il y a XSLT
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Débutant] transformer une variable local en global d'une fonction
    Par bibed dans le forum MATLAB
    Réponses: 3
    Dernier message: 13/11/2009, 22h04
  2. Réponses: 2
    Dernier message: 30/09/2007, 14h35
  3. Variable, local ou global ?
    Par Expender dans le forum Débuter
    Réponses: 4
    Dernier message: 11/06/2007, 16h12
  4. variables locales ou globales?
    Par molesqualeux dans le forum C
    Réponses: 20
    Dernier message: 09/11/2005, 23h03
  5. variables locales ou globales ???
    Par elvivo dans le forum C
    Réponses: 13
    Dernier message: 03/07/2002, 08h22

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