unix 在C中设置环境变量

lxkprmvk  于 2022-11-04  发布在  Unix
关注(0)|答案(5)|浏览(196)

有没有办法在Linux中使用C来设置环境变量?
我尝试了setenv()putenv(),但它们似乎不适合我。

beq87vna

beq87vna1#

我在这里要做一个大胆的猜测,但这些函数看起来不起作用的正常原因不是因为它们不起作用,而是因为用户并不真正理解环境变量是如何工作的。例如,如果我有一个程序:

int main(int argc, char**argv)
{
  putenv("SomeVariable=SomeValue");
  return 0;
}

然后我从shell运行它,它不会修改shell的环境--子进程没有办法这样做。这就是为什么修改环境的shell命令是内置的,也是为什么你需要source一个脚本,其中包含你想添加到你的shell的变量设置,而不是简单地运行它。

6jjcrrmo

6jjcrrmo2#

任何UNIX程序都在一个独立于启动它的进程的进程中运行;这是一个“子”进程。
当一个程序启动时--无论是在命令行还是其他方式--系统都会创建一个新的进程,这个进程(或多或少)是父进程的副本。这个副本包括父进程中的环境变量,这是子进程“继承”其父进程的环境变量的机制。(这是这里其他答案所说的)
也就是说,一个进程只会设置它自己的环境变量。
其他人已经提到了获取shell脚本,作为在当前进程中设置环境变量的一种方法,但是如果您需要以编程方式在当前(shell)进程中设置变量,那么有一种稍微间接的方法是可能的。
请考虑以下内容:

% cat envs.c

# include <stdio.h>

int main(int argc, char**argv)
{
    int i;
    for (i=1; i<argc; i++) {
        printf("ENV%d=%s\n", i, argv[i]);
    }
}
% echo $ENV1

% ./envs one two
ENV1=one
ENV2=two
% eval `./envs one two`
% echo $ENV1
one
%

内置的eval计算它的参数,就像在shell提示符下键入该参数一样。csh样式变体作为练习保留!

e4yzc0pl

e4yzc0pl3#

由setenv()/putenv()设置的环境变量将被设置给执行这些函数的进程,并将被它启动的进程继承。但是,它不会被 * 广播 * 到执行程序的shell中。
为什么我的setenv() Package 器不起作用?

mlnl4t2r

mlnl4t2r4#

环境块是进程本地的,并且被复制到子进程。所以如果你改变变量,新的值只影响你的进程和改变后产生的子进程。当然它不会改变你启动的shell。

brvekthn

brvekthn5#

不是这个问题的答案,只是想说putenv是危险的,请改用setenv

putenv(char *string)是危险的,因为它所做的只是将键值对字符串的地址附加到environ数组中。因此,如果我们随后修改string所指向的字节,所做的更改将影响进程环境。


# include <stdlib.h>

int main(void) {
    char new_env[] = "A=A";
    putenv(new_env);

    // modifying your `new_env` also modifies the environment
    // vairable
    new_env[0] = 'B';
    return EXIT_SUCCESS;
}

由于environ只存储string参数的地址,因此string必须是静态的,以防止出现悬空指针。


# include <stdlib.h>

void foo();

int main(void) {
    foo();
    return EXIT_SUCCESS;
}

void foo() {
    char new_env[] = "A=B";
    putenv(new_env);
}

foo函数的堆栈帧被释放时,new_env的字节消失了,并且存储在environ中的地址变成了悬空指针。

相关问题