C中用putenv修改环境变量
Modify enviroment variable with putenv in C
我正在用 C 编写自己的 shell,我被要求使用函数 putenv(char*) 修改环境变量,我已经实现了这段代码:
char *string = NULL;
if ((string = (char *)malloc(strlen(tokens[2])+strlen(tokens[3])+2)) == NULL){
perror("Error malloc");
return 0;
}
strcpy(string, tokens[2]);
strcat(string, "=");
strcat(string, tokens[3]);
putenv(string);
tokens[2]和tokens[3]分别是变量名和我要给它的新值。
我的问题是,只有当我要求从 extern char **environ 列出环境时,这才有效,但是,当我从 main (char *envp[]) 的第三个参数列出它时,cange 似乎不起作用。
有谁知道如何告诉 putenv() 函数在两者中更改它?
我使用的两种列出环境的方式是:
void ShowEnviroment (char **enviroment, char * name_enviroment)
{
int i=0;
while (enviroment[i]!=NULL) {
printf ("%p->%s[%d]=(%p) %s\n", &enviroment[i],
name_enviroment, i, enviroment[i], enviroment[i]);
i++;
}
}
参数 enviroment
可以是 environ
(定义为 extern char **environ
)(它工作正常)或 &envp
(main 的第三个参数)(是那个似乎没有显示变化)
您的程序运行良好,符合预期。 envp
是程序启动时 environ
的副本,可能与 environ
不同,此后永远不会更新。
对于 运行 命令,shell(例如您正在编写的那个)使用 fork()
+ execv()
的组合——并且 manual on execv
指出
For those forms not containing an envp pointer (execl(), execv(), execlp(), and execvp()), the environment for the new process image shall be taken from the external variable environ in the calling process.
...完全没有提及依赖您收到的envp
,而不是您可能制造的[= =48=] 在使用 do 将修改后的环境变量作为参数的 exec*
变体时,将您选择的任何环境变量传递给子进程。
附带说明一下,使用 setenv()
比 putenv
有两个优点,因此我推荐它:
- 无论您传递给
putenv
什么,都必须及时保留;传递给 setenv
的任何内容都会被复制,因此您无需管理其内存。
- 因此,
setenv(char *key, char *value, int replace)
意味着您的责任更少(并且不需要 malloc、strcat 等)。
两者都会为您修改 environ
。请注意,您不应直接编写 environ
(但读取它很好,并且需要,因为没有 list 可用环境变量的 lsenv
函数);注意 this warning:
Any application that directly modifies the pointers to which the environ variable points has undefined behavior
我正在用 C 编写自己的 shell,我被要求使用函数 putenv(char*) 修改环境变量,我已经实现了这段代码:
char *string = NULL;
if ((string = (char *)malloc(strlen(tokens[2])+strlen(tokens[3])+2)) == NULL){
perror("Error malloc");
return 0;
}
strcpy(string, tokens[2]);
strcat(string, "=");
strcat(string, tokens[3]);
putenv(string);
tokens[2]和tokens[3]分别是变量名和我要给它的新值。 我的问题是,只有当我要求从 extern char **environ 列出环境时,这才有效,但是,当我从 main (char *envp[]) 的第三个参数列出它时,cange 似乎不起作用。
有谁知道如何告诉 putenv() 函数在两者中更改它?
我使用的两种列出环境的方式是:
void ShowEnviroment (char **enviroment, char * name_enviroment)
{
int i=0;
while (enviroment[i]!=NULL) {
printf ("%p->%s[%d]=(%p) %s\n", &enviroment[i],
name_enviroment, i, enviroment[i], enviroment[i]);
i++;
}
}
参数 enviroment
可以是 environ
(定义为 extern char **environ
)(它工作正常)或 &envp
(main 的第三个参数)(是那个似乎没有显示变化)
您的程序运行良好,符合预期。 envp
是程序启动时 environ
的副本,可能与 environ
不同,此后永远不会更新。
对于 运行 命令,shell(例如您正在编写的那个)使用 fork()
+ execv()
的组合——并且 manual on execv
指出
For those forms not containing an envp pointer (execl(), execv(), execlp(), and execvp()), the environment for the new process image shall be taken from the external variable environ in the calling process.
...完全没有提及依赖您收到的envp
,而不是您可能制造的[= =48=] 在使用 do 将修改后的环境变量作为参数的 exec*
变体时,将您选择的任何环境变量传递给子进程。
附带说明一下,使用 setenv()
比 putenv
有两个优点,因此我推荐它:
- 无论您传递给
putenv
什么,都必须及时保留;传递给setenv
的任何内容都会被复制,因此您无需管理其内存。 - 因此,
setenv(char *key, char *value, int replace)
意味着您的责任更少(并且不需要 malloc、strcat 等)。
两者都会为您修改 environ
。请注意,您不应直接编写 environ
(但读取它很好,并且需要,因为没有 list 可用环境变量的 lsenv
函数);注意 this warning:
Any application that directly modifies the pointers to which the environ variable points has undefined behavior