在空环境中,如何找到可执行文件?

kep*_*pla 7 shell binary

出于实验目的,我创建了一个打印$PATH, 并调用which如下的二进制文件:

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

int main() {
    char *path = getenv("PATH");

    if (path)
        printf("got a path: %s\n", path);
    else
        printf("got no path\n");

    system("which which");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我通过以下方式在空环境中运行它时

env -i ./printpath
Run Code Online (Sandbox Code Playgroud)

我得到以下打印输出:

got no path
/usr/bin/which
Run Code Online (Sandbox Code Playgroud)

我的问题是:即使没有,为什么要which调用正确的二进制文件$PATH

cuo*_*glm 11

您已经使用了system函数,因此它将使用另一个 shell 来运行命令which which。来自man system

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)

如果您将which which命令更改为echo $PATH

$ env -i ./a.out 
got no path
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Run Code Online (Sandbox Code Playgroud)

如果您将代码更改为使用execve而不是system,您将获得预期的输出:

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

int main() {                                                                    
    char *path = getenv("PATH");                                                

    if (path)                                                                   
        printf("got a path: %s\n", path);                                       
    else                                                                        
        printf("got no path\n");                                                

    execve("echo $PATH");                                                       
    return 0;                                                                   
} 
Run Code Online (Sandbox Code Playgroud)

编译并运行它:

$ gcc test.c && env -i ./a.out 
got no path
Run Code Online (Sandbox Code Playgroud)