我在Linux中编写了一个C程序来使用setenv
来设置环境变量的值,但是在执行之后,当我运行set
或export
时,环境变量本身似乎是未设置。为什么?
以下是代码段:
int main()
{
char *mallocPtr, *callocPtr, *reallocPtr, *memalignPtr, *vallocPtr;
struct sigaction sa;
sa.sa_handler=SIGSEGV_handler;
sigaction(SIGSEGV, &sa, NULL);
if(setenv("ENV1", "3", 1) == 0)
printf("ENV1 set to 3\n");
else
fprintf(stderr, "setenv failed on ENV1");
答案 0 :(得分:13)
环境变量是在程序的上下文中设置的。
当您的程序退出时,您将回到程序启动的上下文中。
答案 1 :(得分:5)
C库将环境变量视为您可以使用getenv
阅读的全局设置,并使用setenv
/ putenv
进行调整,并继承对exec
系列的调用,但这是一个方便的小说。就内核而言,环境变量是main
的第二组参数。如果您查看exec
系列下的实际系统调用execve
,这一点就变得清晰了。这是它的C原型:
int execve(const char *filename, char *const argv[], char *const envp[]);
^^^^^^^^^^^^^^^^^^
看到第三个参数?这是进程A设置进程B的环境变量的唯一方式。 1 因此,唯一的时间进程A可以设置进程B的环境变量是当流程A 启动流程B时,通过fork
和execve
。
您的程序是通过 shell启动的,因此shell必须设置其环境变量的副本,但是没有办法将更改推送回shell - 就像C函数无法在其调用者中更改其参数的值。
1 不要提起ptrace
。
答案 2 :(得分:1)
实际上每个进程都有自己的envp
char数组。 main
函数具有以下签名:
int main(int argc, char *argv[], char *envp[])
通常,父级的envp
继承父级子层次结构的子级。它绝不会在父子层级中向上传达。