web-dev-qa-db-fra.com

Définir les variables d'environnement en C

Existe-t-il un moyen de définir des variables d'environnement sous Linux à l'aide de C?

J'ai essayé setenv() et putenv(), mais ils ne semblent pas fonctionner pour moi.

31
iman453

Je vais faire une supposition sauvage ici, mais la raison normale pour laquelle ces fonctions semblent ne pas fonctionner n'est pas parce qu'elles ne fonctionnent pas, mais parce que l'utilisateur ne comprend pas vraiment comment fonctionnent les variables d'environnement. Par exemple, si j'ai ce programme:

int main(int argc, char **argv)
{
  putenv("SomeVariable=SomeValue");
  return 0;
}

Et puis je l'exécute à partir du shell, cela ne modifiera pas l'environnement du shell - il n'y a aucun moyen pour un processus enfant de le faire. C'est pourquoi les commandes Shell qui modifient l'environnement sont intégrées et pourquoi vous devez source un script qui contient des paramètres variables que vous souhaitez ajouter à votre Shell, plutôt que de simplement l'exécuter.

47
Carl Norum

Tout programme Unix s'exécute dans un processus distinct du processus qui le démarre; il s'agit d'un processus "enfant".

Lorsqu'un programme est démarré - que ce soit sur la ligne de commande ou de toute autre manière - le système crée un nouveau processus qui est (plus ou moins) une copie du processus parent. Cette copie inclut les variables d'environnement dans le processus parent, et c'est le mécanisme par lequel le processus enfant "hérite" des variables d'environnement de son parent. (c'est en grande partie ce que d'autres réponses ont dit ici)

Autrement dit, un processus uniquement toujours définit ses variables d'environnement propres.

D'autres ont mentionné la source d'un script Shell, comme un moyen de définir des variables d'environnement dans le processus en cours, mais si vous devez définir des variables dans le processus (Shell) en cours par programme, il existe une manière légèrement indirecte que c'est possible.

Considère ceci:

% cat envs.c
#include <stdio.h>
int main(int argc, char**argv)
{
    int i;
    for (i=1; i<argc; i++) {
        printf("ENV%d=%s\n", i, argv[i]);
    }
}
% echo $ENV1

% ./envs one two
ENV1=one
ENV2=two
% eval `./envs one two`
% echo $ENV1
one
% 

Le eval intégré évalue son argument comme si cet argument avait été tapé à l'invite du shell. Ceci est un exemple de style sh; la variante de style csh est laissée en exercice!

10
Norman Gray

La variable d'environnement définie par setenv ()/putenv () sera définie pour le processus qui a exécuté ces fonctions et sera héritée par les processus lancés par celle-ci. Cependant, il ne sera pas diffusé dans le shell qui a exécuté votre programme.

Pourquoi mon wrapper autour de setenv () ne fonctionne-t-il pas?

5
karlphillip

Le bloc d'environnement est local au processus et copié dans les processus enfants. Ainsi, si vous modifiez des variables, la nouvelle valeur affecte uniquement votre processus et les processus enfants générés après la modification. Assurément, cela ne changera pas le Shell à partir duquel vous avez lancé.

1
Ben Voigt