I wrote a C program in Linux to set the values of environment variables using setenv
, but after execution, when I run set
or export
, the environment variable itself seems to be unset. Why?
我在Linux中编写了一个C程序来使用setenv设置环境变量的值,但是在执行之后,当我运行set或export时,环境变量本身似乎没有设置。为什么?
Here is the code snippet:
这是代码片段:
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");
3 个解决方案
#1
13
The environment variables are set within the context of your program.
环境变量在程序的上下文中设置。
When your program exits, you're back in the context from where your program was started.
当您的程序退出时,您将回到程序启动的上下文中。
#2
4
The C library treats environment variables as global settings you can read with getenv
and adjust with setenv
/putenv
, and that inherit across calls to the exec
family, but that is a convenient fiction. As far as the kernel is concerned, the environment variables are a second set of arguments to main
. This becomes clear if you look at the actual system call, execve
, underlying the exec
family. This is its C prototype:
C库将环境变量视为可以使用getenv读取的全局设置,并使用setenv / putenv进行调整,并且继承调用exec系列,但这是一个方便的小说。就内核而言,环境变量是main的第二组参数。如果你看一下exec系列的实际系统调用execve,这就变得很清楚了。这是它的C原型:
int execve(const char *filename, char *const argv[], char *const envp[]);
^^^^^^^^^^^^^^^^^^
See that third argument? That's the only way for process A to set process B's environment variables.1 Therefore, the only time process A can set process B's environment variables is when process A starts process B, via fork
and execve
.
看到第三个论点?这是进程A设置进程B的环境变量的唯一方法。因此,进程A可以设置进程B的环境变量的唯一时间是进程A通过fork和execve启动进程B的时间。
Your program is started by the shell, so the shell got to set its copy of the environment variables, but there is no way for it to push a change back to the shell -- just as there is no way for a C function to change the values of its arguments in its caller.
你的程序是由shell启动的,所以shell必须设置它的环境变量副本,但它没有办法将更改推回到shell - 就像C函数无法改变一样其参数在其调用者中的值。
1 Do not bring up ptrace
.
1不要提起ptrace。
#3
1
Actually every process has its own envp
char array. The main
function has the following signature:
实际上每个进程都有自己的envp char数组。主要功能有以下签名:
int main(int argc, char *argv[], char *envp[])
Usually, the envp
of the parent inherit to the child, down the parent-child hierarchy. It is by no means communicated upwards in the parent-child hierarchy.
通常,父级的envp继承父级子层次结构的子级。它绝不是在父子层次结构中向上传达的。
#1
13
The environment variables are set within the context of your program.
环境变量在程序的上下文中设置。
When your program exits, you're back in the context from where your program was started.
当您的程序退出时,您将回到程序启动的上下文中。
#2
4
The C library treats environment variables as global settings you can read with getenv
and adjust with setenv
/putenv
, and that inherit across calls to the exec
family, but that is a convenient fiction. As far as the kernel is concerned, the environment variables are a second set of arguments to main
. This becomes clear if you look at the actual system call, execve
, underlying the exec
family. This is its C prototype:
C库将环境变量视为可以使用getenv读取的全局设置,并使用setenv / putenv进行调整,并且继承调用exec系列,但这是一个方便的小说。就内核而言,环境变量是main的第二组参数。如果你看一下exec系列的实际系统调用execve,这就变得很清楚了。这是它的C原型:
int execve(const char *filename, char *const argv[], char *const envp[]);
^^^^^^^^^^^^^^^^^^
See that third argument? That's the only way for process A to set process B's environment variables.1 Therefore, the only time process A can set process B's environment variables is when process A starts process B, via fork
and execve
.
看到第三个论点?这是进程A设置进程B的环境变量的唯一方法。因此,进程A可以设置进程B的环境变量的唯一时间是进程A通过fork和execve启动进程B的时间。
Your program is started by the shell, so the shell got to set its copy of the environment variables, but there is no way for it to push a change back to the shell -- just as there is no way for a C function to change the values of its arguments in its caller.
你的程序是由shell启动的,所以shell必须设置它的环境变量副本,但它没有办法将更改推回到shell - 就像C函数无法改变一样其参数在其调用者中的值。
1 Do not bring up ptrace
.
1不要提起ptrace。
#3
1
Actually every process has its own envp
char array. The main
function has the following signature:
实际上每个进程都有自己的envp char数组。主要功能有以下签名:
int main(int argc, char *argv[], char *envp[])
Usually, the envp
of the parent inherit to the child, down the parent-child hierarchy. It is by no means communicated upwards in the parent-child hierarchy.
通常,父级的envp继承父级子层次结构的子级。它绝不是在父子层次结构中向上传达的。