使用C代码获取环境变量

use*_*679 8 c linux embedded

在这里,我写了一个hi.sh使用systemcall 执行文件的C程序.

在这里我使用了. ./hi.sh所以我想在同一个shell中执行这个脚本,然后尝试使用getenv函数获取环境变量,但是在这里我得到了我预期的不同输出.

hi.sh文件包含

export TEST=10
return
Run Code Online (Sandbox Code Playgroud)

表示当我hi.sh使用系统调用运行此文件时,它export TEST在同一个shell中将值设置为10.在此之后,我试图得到这个变量值但它的给定NULL值.

如果我从控制台手动运行这个脚本,. ./hi.sh那么它工作正常,我得到10个TEST使用getenv("TEST")函数的值.

码:

#include <stdio.h>
int main()
{
    system(". ./hi.sh");
    char *errcode;
    char *env = "TEST";
    int errCode;    
    errcode = getenv(env);
    printf("Value is = %s\n",errcode);
    if (errcode != NULL) {
        errCode =atoi(errcode);
        printf("Value is = %d\n",errCode);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Value is = (null)
Run Code Online (Sandbox Code Playgroud)

如何在程序shell中导出TEST变量?如果system()在不同的shell中执行命令,那么如何使用C程序代码来获取由通过调用调用的shell导出的环境变量system()

Jon*_*ler 9

子进程无法直接设置父进程的环境.因此,使用system()getenv()注定失败的方法.

如果您尝试导入脚本设置的选定变量hi.sh,那么您有几个选择.您可以阅读脚本hi.sh并找出它将设置它们的内容(相当难),或者您可以运行脚本并让您运行的代码报告回感兴趣的环境变量.

假设hi.sh$ENV1$ENV2.您可以使用popen()将值返回到程序,以及setenv()设置程序的环境.概述:

FILE *fp = popen(". ./hi.sh; echo ENV1=$ENV1; echo ENV2=$ENV2", "r");

while (fgets(buffer, sizeof(buffer), fp) != 0)
{
    ...split the buffer into env_name, env_value...
    setenv(env_name, env_value);
}

pclose(fp);
Run Code Online (Sandbox Code Playgroud)

请注意,我在变换信息中包含了变量名称; 这简化了生活.如果您的变量列表变得". ./hi.sh; env"难以处理,可能您可以运行以获取整个环境,然后读取每一行并从内置列表中找出它是否是您要使用的变量设置.或者你可以简单地再次设置你的整个环境,如果这让你高兴的话.您应该检查setenv()函数是否成功(当它成功时它返回零).您还应该检查popen()是否成功(fp != 0).在这种情况下,您可能可以使用strtok()来查找=从值中分离变量名称; 它会覆盖空字节=,给出一个空终止名称和一个空终止值:

    char *env_name = strtok(buffer, "=");
    char *env_value = buffer + strlen(env_name) + 1;
    if (setenv(env_name, env_value) != 0)
        ...report trouble...
Run Code Online (Sandbox Code Playgroud)


Kri*_*ost 7

与往常一样,手册页确实解释了这一点,但您需要非常仔细地阅读它.

DESCRIPTION
       system()  executes a command specified in command by calling /bin/sh -c
       command, and returns after the command has been completed.  During exe?
       cution  of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT
       will be ignored.
Run Code Online (Sandbox Code Playgroud)

换句话说,system()首先启动/ bin/sh,然后让/ bin/sh启动你想要执行的任何命令.所以这里发生的是TEST变量被导出到/ bin/sh shell,而system()调用是隐式启动的,而不是调用system()的程序.

  • @ user1089679在运行C程序之前获取脚本(设置环境).这就是设计使用环境变量的方式. (2认同)