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 :

[bash] Commande echo fils et variable


Sujet :

Shell et commandes GNU

  1. #1
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Par défaut [bash] Commande echo fils et variable
    bonjour

    j'ai crée une variable
    var=toto

    quand je fais echo $var, je vois bien toto s'afficher

    par contre
    quand je fais (echo $var) toto s'affiche aussi (alors que je lance un fils et que je n'ai pas exporte la variable)

    En effet cela ne sert a rien.....mais c'est juste pour comprendre pourquoi la variable est reconnu dans le fils sans export...

    Merci d'avance

  2. #2
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    le principe est le même que pour un fork() en C, ici avec la variable msg par exemple :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <unistd.h>
    #include <stdio.h>
     
    int main (void) {
       char *msg = "je suis le processus";
       pid_t pid = fork();
       if (pid == 0) printf ("%s fils\n", msg);
       else printf ("%s père\n", msg);
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ gcc -Wall pouet.c -o pouet
    $ ./pouet
    je suis le processus père
    je suis le processus fils
    le processus fils connait le contexte du père, l'inverse n'est pas vrai, si on set une variable dans le sous-processus le père n'en aura pas connaissance
    dans le détail il faudrait s'en assurer néanmoins (cf code source de bash pour les courageux ), aussi bien bash gère peut-être son subshell comme une coroutine ou un thread selon le cas (quand il ne détecte que des commandes builtins dans les parenthèses par exemple)

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

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

    Ok
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ var=toto
    $ echo $var" pere";(echo "$var fils";var=tata;echo $var" fils");echo "$var pere"                                                                                                                         
    toto pere
    toto fils
    tata fils
    toto pere
    La comparaison avec le C/C++ est hasardeuse car les scripts bash détonent justement par 2 choses:
    • En plein milieu d'une commande, il y a création d'un sous-shell dont les variables ne seront pas récupérables. Et c'est déstabilisant quand on débute.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      cat ... | sed ... | while ... do variable="valeur"... done
      echo $variable
       
      (rien alors qu'on attend 'valeur')
    • Les fonctions n'ont pas besoin de passage de paramètres puisque tout est disponible directement. C'est, au contraire, l'attribution d'une portée locale, qui doit être indiqué.
      Exemple:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      $ totof() { local var=truite;echo $var; } 
       
      $ totof; echo $var
      truite
      toto

  4. #4
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Par défaut
    merci pour vos reponses

    il y a création d'un sous-shell dont les variables ne seront pas récupérables...

    justement le fait de faire echo $var ; (echo $var)...je pensais correspondre a ton deuxième exemple

    creation d'un sous shell (....), je pensais que la 2eme commande ne connaitrait pas la variable defini par le pere, je pensais qu'il y avait besoin d'un export

    merci pour les exemples :-)

  5. #5
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par dancewithme Voir le message
    par contre
    quand je fais (echo $var) toto s'affiche aussi (alors que je lance un fils et que je n'ai pas exporte la variable)
    Les explications données jusqu'ici ne décrivent pas exactement ce qui se passe dans ton test.

    Quand tu executes:
    C'est le shell courant (le parent donc) qui interprète $var, le sous-shell exécute simplement la commande
    et ta question sur l'exportation n'est pas tranchée.

    Si en revanche tu exécutes:
    là, le sous shell va bien exécuter "echo $var" mais il va quand même afficher toto.

    Pourquoi ? Et bien parce qu'un sous shell n'est pas un autre processus lancé par la séquence habituelle fork/exec mais uniquement le clone du shell courant, obtenu par un simple fork, comme l'a justement déjà indiqué BufferBob. Comme c'est le "même" programme (au pid et program counter près), il hérite de tout le contexte du parent, y compris les variables non exportées. La comparaison avec le C n'est donc pas si hasardeuse que ça...

    Si tu avais lancé un autre shell, la variable toto aurait été perdue sauf si exportée au préalable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ a=toto
    $ sh -c "echo $a" # même erreur quand dans (echo $a), la variable est traitée avant l'exécution de "sh -c"
    toto
    $ sh -c "echo \$a" # la variable n'est pas interprétée par le shell courant, rien ne s'affiche 
     
    $ export a
    $ sh -c "echo \$a" # la variable est exportée, le shell fils affiche sa valeur
    toto

  6. #6
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Par défaut
    Merci pour ces précisions.
    Je comprend maintenant.

  7. #7
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    En plein milieu d'une commande, il y a création d'un sous-shell dont les variables ne seront pas récupérables. Et c'est déstabilisant quand on débute.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    cat ... | sed ... | while ... do variable="valeur"... done
    echo $variable
     
    (rien alors qu'on attend 'valeur')
    C'est vrai, mais avec les versions récentes de bash, il y a une solution à ce défaut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ cat demo
    #!/bin/bash
    cat /dev/null | sed 's///' | while test -z "$variable" ;  do variable="valeur";  done
    echo variable=$variable
    shopt -s lastpipe # Spécifique à bash
    cat /dev/null | sed 's///' | while test -z "$variable" ;  do variable="valeur";  done
    echo variable=$variable
    $ ./demo
    variable=
    variable=valeur
    Ce comportement plus intuitif est d'ailleurs le choix qu'a fait ksh, dommage que POSIX ne l'ait pas imposé.

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Très intéressant tout ça.

    On avait toujours la solution de la substitution de processus avec bash:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while test -z "$variable" ;  do variable="valeur";  done < <(cat /dev/null | sed 's///')

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Pardon pour le double-post.

    Comment faire pour que, à la place de "echo $var", il y ait l'affichage du pid du sous-processus ?
    Parce que là, si je tape (echo $$), il me renvoie le pid du père.
    Mais si je fais le bilan ps -fe, il me montre bien 2 processus bash dont l'un est le fils de l'autre.

    Confusion pour moi.

  10. #10
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    C'est une conséquence du fork sans exec déjà évoqué.

    Le sous-shell hérite du contexte complet de son shell parent, les variables PID et PPID incluses.

    Sous bash, il existe cependant une variable particulière, BASHPID qui contient le vrai pid du shell courant. Si $PID est différent de $BASHPID, c'est donc qu'on est dans on sous-shell.

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

Discussions similaires

  1. option -e de la commande echo possible par variable ?
    Par voran dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 17/01/2008, 09h53
  2. Réponses: 6
    Dernier message: 23/07/2007, 21h56
  3. [Débutant] Implémentation commande echo
    Par Tuxico dans le forum C
    Réponses: 14
    Dernier message: 10/10/2006, 14h49
  4. Réponses: 22
    Dernier message: 09/12/2005, 21h27
  5. Comment aller a la ligne avec la commande ECHO
    Par juflata dans le forum Windows
    Réponses: 3
    Dernier message: 23/06/2004, 17h11

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