2011-10-05 6 views
8

Nous éprouvons beaucoup de difficultés à interpréter notre professeur. Nous avons demandé des éclaircissements et avons obtenu ce qui suit éloignèrent de luiComprendre les exigences pour les environnements d'exécution et de réglage

  1. Pour exec, envoyez un environnement vous configurez vos variables exportées et créer une commande builtin pour frayer un sous-shell/bin/bash, de cette façon vous pouvez voir vos variables exportées en utilisant env.

    (Il parle de la création de notre propre environnement vars ici.)

  2. Oui créer votre propre. Vous pouvez commencer par copier environ lorsque votre shell démarre et ajouter uniquement les variables exportées

Ceci est lié au post suivant sur Stack Overflow par moi (lire cet autre article vous aidera à comprendre ce que j'essaie de faire):

using a new path with execve to run ls command

Nous sommes juste très confus à ce sujet. Une fois de plus, je vais expliquer ce que nous essayons de faire maintenant. De la même manière que votre shell Linux le fait, nous devons écrire notre propre programme qui peut définir des variables d'environnement telles que PATH et USER et toutes les autres variables que l'utilisateur veut définir.

Un exemple de la façon dont vous appelez ce serait (à l'intérieur de votre programme à l'invite):

mysetenv dog spike 

qui créerait une variable d'environnement ressemblant à « chien = pic »

Plus important encore, nous devons être en mesure de définir notre propre variable PATH et l'envoyer à une commande exec. C'est une partie déroutante parce que, d'après toutes nos questions, nous ne comprenons pas ce que nous sommes censés faire.

Répondre

26

C'est en fait très simple. Vous savez déjà que vos arguments sont une liste de char *, terminée par un pointeur NULL. De même, l'environnement est simplement une liste de char *, terminée par un pointeur NULL. Classiquement, les valeurs dans la liste prennent la forme VARNAME=var-value, bien que vous puissiez passer d'autres formats si vous le souhaitez.

Ainsi, pour prendre un cas simple:

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

int main(void) 
{ 
    char *argv[] = { "/bin/sh", "-c", "env", 0 }; 
    char *envp[] = 
    { 
     "HOME=/", 
     "PATH=/bin:/usr/bin", 
     "TZ=UTC0", 
     "USER=beelzebub", 
     "LOGNAME=tarzan", 
     0 
    }; 
    execve(argv[0], &argv[0], envp); 
    fprintf(stderr, "Oops!\n"); 
    return -1; 
} 

Dans cet exemple, le programme se déroulera /bin/sh avec des arguments -c et env, ce qui signifie que le shell exécute le programme env trouvé sur son chemin actuel. L'environnement ici est configuré pour contenir 5 valeurs dans le format orthodoxe. Si vous modifiez env à date (ou env; date), vous verrez l'effet du paramètre TZ, par exemple. Quand je lance que sur ma machine MacOS X, la sortie est:

USER=beelzebub 
PATH=/bin:/usr/bin 
PWD=/Users/jleffler/tmp/soq 
TZ=UTC0 
SHLVL=1 
HOME=/ 
LOGNAME=tarzan 
_=/usr/bin/env 

La coque a ajouté des variables d'environnement SHLVL, _ et PWD à ceux que je définir explicitement dans l'appel execve().

Vous pouvez également faire des choses plus fantaisistes, telles que copier dans certaines des autres variables d'environnement de votre environnement authentique où elles ne sont pas en conflit avec celles que vous souhaitez définir explicitement.Vous pouvez également jouer à des jeux comme avoir deux valeurs pour une seule variable dans l'environnement - laquelle prend effet? Et vous pouvez jouer à des jeux avec des noms de variables contenant des espaces (le shell n'aime pas beaucoup), ou des entrées qui ne correspondent pas du tout à la notation 'varname = value' (pas de signe égal).

+0

Vous avez vraiment effacé tout cela pour moi. J'ai déjà tout retourné, mais merci! Je comprends maintenant. – james

1

Le code de Jonathan Leffler fonctionne très bien, sauf si vous voulez changer la variable PWD (répertoire de travail).

Ce que je l'ai fait, pour changer le répertoire de travail, était de mettre un chdir(..) avant execve(..) et appeler:

chdir("/foo/bar"); 
execve(argv[0], &argv[0], envp); 
0

Je suis un peu en retard à la fête, mais si vous voulez préserver les vieilles variables d'environnement ainsi que la création de votre propre, utilisez setenv, puis passez environ à execve().

setenv("dog", "spike", 1); 
    extern char** environ; 
    execve(argv[0], argv, environ); 

environ est une variable déclarée dans unistd.h, et il garde la trace des variables d'environnement au cours de ce processus en cours.

setenv() et putenv() modifier environ, donc quand vous passez sur execve(), les variables d'environnement sera tout comme vous vous attendez.

Questions connexes