如何使用execve或execvp来打印$ PATH

时间:2018-03-05 19:38:09

标签: c system-calls

当我使用终端运行echo $PATH命令时,它将显示PATH环境变量。

例如,类似这样的内容:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

但是,当我使用execvp()来调用它时,它只会打印字符串" $ PATH"。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>

int main(int argc, const char* argv[]) {
    char* a[] = {"echo", "$PATH", NULL};
    execvp("echo", a);
    exit(0);
}

输出为:$PATH

如何使用execvp()正确回显环境变量?

3 个答案:

答案 0 :(得分:3)

execvp不会运行shell,所以env。变量将不会被评估。

使用system会起作用,因为它在shell中运行命令:

system("echo $PATH");

虽然对于这个特殊情况,最简单的&amp;最干净的是getenv(这也更便携:也适用于Windows)

const char *value = getenv("PATH");
if (value!=NULL)
{
   puts(value);
}

答案 1 :(得分:2)

$(在$PATH中)由shell处理。阅读shell parameter expansion

如果您只想将PATH variable使用getenv(3)作为getenv("PATH")(不需要使用main的第三个参数,那么answered by t0mm13b )。

如果您坚持在execvp之前获取该内容,则需要exec /bin/sh -c "echo $PATH"之类的内容(因此execvpa的三个非空参数,最后一个非空的是"echo $PATH"字符串)。

如果您坚持要显示所有环境变量(请参阅environ(7) ...),您可以使用extern char **environ;全局变量,或使用env(1)程序(不带参数)或printenv(1)一个。 crt0启动例程会设置environ

答案 2 :(得分:1)

第三个参数对main的使用,是如何获取所使用的环境变量。当运行时加载程序执行代码时,参数count,arguments和environment变量将传递给启动。

输出将包含一个字符串,该字符串具有由=

分隔的环境变量名称和值
int main(int argc, char **argv, char **envp){
    while (*envp){
        printf("%s\n", *envp++);
    }
}

例如,请参阅此ideone snippet

结果类似于:

  

PATH =的/ usr / local / bin中:在/ usr / bin中:/ bin中

编辑而不是循环遍历所有环境变量,只需获取一个,使用strstr查找包含PATH的字符串,然后添加长度从strstr返回的指针的字符串“PATH =”将产生环境变量PATH的值

int main(int argc, char **argv, char **envp){
    while (*envp){
        char *ptrPath = strstr(*envp, "PATH");
        if (ptrPath) printf("%s\n", (ptrPath+5));
        *envp++;
    }
    return 0;
}

第二次修改:

正如@jonathanleffler指出我的boo-boo,这是编辑,完成字符串操作以获得字符串“PATH”的完全匹配。

int main(int argc, char **argv, char **envp){
    while (*envp){
        char *ptrPath = strstr(*envp, "PATH");
        char *exact = NULL;
        if (ptrPath){
            char *ptrDelim = strrchr(*envp, '=');
            if (ptrDelim){
                size_t ptrDelimLen = (ptrDelim - *envp + 1);
                exact = malloc(ptrDelimLen + 1);
                strncpy(exact, *envp, ptrDelimLen);
                exact[ptrDelimLen - 1]='\0';
                if (!strcmp(exact, "PATH") && strlen(exact) == 4){
                    printf("%s\n", (ptrPath+5));
                }
            }
        }
        *envp++;
    }
    return 0;
}