【发布时间】:2022-01-09 08:31:29
【问题描述】:
我正在用 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的参数main是来自父进程的输入环境only。而且你真的不应该使用envp或environ。 POSIX 标准本身建议只使用getenv来访问进程环境。 -
string = malloc(); strcpy(string...无效。在 malloc 之后,string不是以 null 结尾的字符串,所以不能使用strcpy。在strcpy之前需要string[0] = '\0'(或者只使用sprintf) -
@WilliamPursell No
strcpy没问题,因为string是 destination(并且其内容被覆盖)。也许您正在考虑strcat,其中目标必须是正确的以空字符结尾的字符串? -
@Someprogrammerdude 是的,我在想
strcat。屏幕太多,咖啡太少......不过,我肯定更喜欢sprintf。 -
The Glibc documentation indicates that
envphas the same value asenviron。当然,这必须被解释为这些的 initial 值。如果添加额外的环境变量,那么可能需要分配不同的、更大的空间,这似乎是合理的。在这种情况下,人们会期望environ会更新,但envp是main的本地,因此无法(自动)更新。