Forum Programmation.c environnement non transmis par variable environ

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
19
déc.
2016

bonjour,
je suis en train d'étudier "développement système sous linux" de Christophe Blaess.
Je tombe sur un os, et pas des moindres.
je cherche à transmettre l'environnement de mon shell par la variable extern char **environ;
mais rien n'y fait. Ma variable $SHLVL n'est pas incrémentée lors de l'appel au programme du livre.
voici le contenu de mon programme:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

extern char **environ;

int main(int argc, char ** argv)
{
char* args[] = {"sh", "-c", "echo $SHLVL", (char*) NULL};
execve("/bin/sh", args, environ);
return EXIT_SUCCESS;
}

et à son exécution:

gunsailor@soulfly:~$ echo $SHLVL
1
gunsailor@soulfly:~$ ./test
1
gunsailor@soulfly:~$ 

si quelqu'un a une idée je suis preneur !!!!!!!!!

  • # Processus et processus fils

    Posté par  (site web personnel) . Évalué à 4.

    Nb: éviter d'utiliser test.c et test comme nom de programme, pour ne pas se retrouver à lancer /bin/test involontairement…

    $ test
    $ ./test
    1 coin

    Du coup je garde mon a.out comme nom d'exécutable.

    En remplaçant sh par bash deux fois :

    $ ./a.out 
    2

    Et tant qu'on y est avec char* args[] = {"sh", "-c", "echo $SHLVL $a", (char*) NULL};

    $ unset a ; ./a.out 
    1
    $ unset a ; a=coin ; ./a.out 
    1
    $ unset a ; export a=coin ; ./a.out 
    1 coin
    $ unset a ; declare -x a=coin ; ./a.out 
    1 coin
    • [^] # Re: Processus et processus fils

      Posté par  . Évalué à 1.

      ce commentaire est inutile.
      j'ai quand même essayé de renommer mon exécutable, rien n'y fait.
      la variable $SHLVL devrait être incrémentée au fur et à mesure des appels.
      que se passe-t-il?

      • [^] # Re: Processus et processus fils

        Posté par  . Évalué à 3.

        Bonjour,

        la variable $SHLVL devrait être incrémentée au fur et à mesure des appels.

        Oui, au fur et à mesure des appels à bash (c'est une variable interne à bash, elle ne fonctionne pas avec sh).

        En remplaçant /bin/sh par /bin/bash le résultat devrait être le bon, comme l'a indiqué Benoît dans le commentaire précédent.

        Matricule 23415

  • # mais il reste un problème

    Posté par  . Évalué à 1.

    voici la sortie du programme répertorié dans le livre de christophe blaess:

    echo $SHLVL
    1
    ./exemple-execve
    2
    sh
    ./exemple-execve
    3
    exit
    ./exemple-execve
    2

    avec pour fichier c:

    extern char ** environ;
    int main(int argc, char ** argv)
    {
    char* args[]= {"bash", "-c", "echo $SHLVL", (char*) NULL};
    execve("/bin/bash", args, environ);
    return EXIT_SUCCESS;
    }

    et ceci seulement après avoir changé les "sh" en "bash".
    l'appel à un autre shell par "sh", ne modifie pas le nombre contenu dans la variable $SHLVL.

    gunsailor@soulfly:~$ echo $SHLVL
    1
    gunsailor@soulfly:~$ ./exemple-execve
    2
    gunsailor@soulfly:~$ sh
    $ ./exemple-execve

    2

    je n'avait pas bien compris l'allusion de Benoît. désolé.
    mais cela ne fonctionne toujours pas!
    avez-vous des retours sur ce bouquin ?
    merci d'avance

    • [^] # Re: mais il reste un problème

      Posté par  (site web personnel) . Évalué à 4.

      Les mêmes causes produisent les mêmes effets :

      $ echo $SHLVL
      1
      $ ./exemple-execve
      2
      $ bash
      $ ./exemple-execve
      3
      $ sh
      $ ./exemple-execve
      3
      $ exit
      exit
      $ exit
      exit
      $ ./exemple-execve
      2
      for shell in /bin/sh /bin/dash /bin/bash /bin/mksh /bin/mksh-static /usr/bin/tmux /bin/zsh /usr/bin/zsh ; do echo $SHLVL ; echo "avant $shell" ; $shell -c "./exemple-execve ; exit" ; echo "après $shell" ; done ; echo $SHLVL
      1
      avant /bin/sh
      2
      après /bin/sh
      1
      avant /bin/dash
      2
      après /bin/dash
      1
      avant /bin/bash
      3
      après /bin/bash
      1
      avant /bin/mksh
      2
      après /bin/mksh
      1
      avant /bin/mksh-static
      2
      après /bin/mksh-static
      1
      avant /usr/bin/tmux
      3
      après /usr/bin/tmux
      1
      avant /bin/zsh
      3
      après /bin/zsh
      1
      avant /usr/bin/zsh
      3
      après /usr/bin/zsh
      1

      Quels shells se préoccupent de la variable SHLVL (visiblement bash et zsh au moins) ?

      $ for shell in /bin/sh /bin/dash /bin/bash /bin/mksh /bin/mksh-static /usr/bin/tmux /bin/zsh /usr/bin/zsh ; do grep -H -c SHLVL $shell ; done
      /bin/sh:0
      /bin/dash:0
      /bin/bash:1
      /bin/mksh:0
      /bin/mksh-static:0
      /usr/bin/tmux:0
      /bin/zsh:1
      /usr/bin/zsh:1
      
      $ for shell in /bin/bash /bin/zsh ; do echo $shell ; strings $shell|grep SHLVL ; done
      /bin/bash
      SHLVL
      /bin/zsh
      SHLVL
      

      Et les pages de manuel :

      man bash
             SHLVL  Incrémenté de 1 à chaque appel d'une instance de bash.
      
      man zshparam
            SHLVL <S>
                    Incremented by one each time a new shell is started.
      
  • # résolu

    Posté par  . Évalué à 1.

    merci d'avoir pris le temps d'examiner cela avec moi et de décortiquer pour moi ces commandes.
    Je vais me méfier de tout ce qu'il y a marqué dans ce bouquin désormais.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.