简体   繁体   中英

How to use execve or execvp to print $PATH

When I use terminal to run echo $PATH command, it will show the PATH environment variable.

For example, something like this: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

However, when I use execvp() to call it, it will only print the string "$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);
}

The output is: $PATH .

How could I use execvp() to echo environment variables correctly?

execvp won't run a shell, so env. variables won't be evaluated.

Using system would work because it runs commands in a shell:

system("echo $PATH");

although for this particular case the simplest & cleanest would be getenv (which is also more portable: also works on Windows)

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

The $ (in $PATH ) is processed by a shell. Read about shell parameter expansion .

If you just want to get the PATH variable use getenv(3) as getenv("PATH") (there is no need to use the third argument to main , as answered by t0mm13b ).

If you insist in getting that by execvp you need to exec something like /bin/sh -c "echo $PATH" (so three non-null arguments to execvp in your a , the last non-null one being the "echo $PATH" string).

If you insist on showing all the environment variables (see environ(7) ...) you might use the extern char **environ; global variable, or use the env(1) program (without arguments) or the printenv(1) one. The crt0 startup routine would set up that environ .

The usage of the third parameter to main , is how to obtain the environment variables used. When the runtime loader executes the code, the argument count, arguments and environment variables are passed into the startup.

The output would contain a string that has environment variable name and value that is delimited by an =

int main(int argc, char **argv, char **envp){
    while (*envp){
        printf("%s\n", *envp++);
    }
}

For example, see this ideone snippet

Result would be similar as:

PATH=/usr/local/bin:/usr/bin:/bin

Edit: Instead of looping through all the environment variables, just to get one, use strstr to find the string that contains PATH , then, add the length of the string "PATH=" to the pointer retuned from strstr will yield the value for the environment variable 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;
}

Second Edit:

As @jonathanleffler pointed out my boo-boo, here's the edit, that is complete with string manipulate to get the exact match of the string "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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM