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?
Here is th开发者_如何学运维e 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");
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.
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:
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
.
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.
1 Do not bring up ptrace
.
Actually every process has its own envp
char array. The main
function has the following signature:
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.
精彩评论