빈 환경에서 실행 파일을 어떻게 찾을 수 있나요?

빈 환경에서 실행 파일을 어떻게 찾을 수 있나요?

실험 목적으로 다음과 같이 $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;
}

빈 환경에서 실행했을 때

env -i ./printpath

나는 다음과 같은 인쇄물을 얻습니다.

got no path
/usr/bin/which

내 질문은 다음과 같습니다which그렇지 않더라도 올바른 바이너리가 호출되는 이유는 무엇입니까 $PATH?

답변1

function을 사용했으므로 system다른 쉘을 사용하여 명령을 실행합니다 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.

which which명령을 다음으로 변경 하면 echo $PATH:

$ env -i ./a.out 
got no path
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

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;                                                                   
} 

컴파일하고 실행합니다:

$ gcc test.c && env -i ./a.out 
got no path

답변2

빈 환경에서는 전체 경로를 지정하지 않으면 실행 파일을 찾을 수 없습니다. 시도 해봐 execvp.

system함수는 쉘을 호출합니다. Linux에서는 Glibc를 사용하여 쉘을 호출합니다 /bin/sh(따라서 PATH필요하지 않습니다). 환경의 변수 외에도 쉘은 자체 변수 중 일부를 정의합니다. 이를 실행하여 정의한 내용 env -i /path/to/shell -c set과 실행하여 내보내는 내용을 볼 수 있습니다 env -i /path/to/shell -c export. 특히 dash 및 bash(Linux에서 찾을 수 있는 두 개의 셸)는 /bin/sh환경에 없으면 "일반" 기본값으로 설정됩니다(내보낼 수 없음). PATH다른 쉘은 다른 값을 설정하거나 전혀 설정하지 않습니다.

$ env -i bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ env -i dash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ env -i mksh -c 'echo $PATH'
/usr/bin:/bin
$ env -i ksh93 -c 'echo $PATH'

$ env -i zsh -c 'echo $PATH' 
/bin:/usr/bin:/usr/ucb:/usr/local/bin
$ env -i csh -c 'echo $PATH' 
PATH: Undefined variable.
$ env -i tcsh -c 'echo $PATH'
PATH: Undefined variable.

내 컴퓨터에서는 (그리고 분명히 당신의 컴퓨터에서도 마찬가지입니다) which/bin/sh자체가 스크립트입니다. 호출 쉘은 프로그램을 system찾기 위해 자신의 경로 변수를 사용 which하지만 내보내지는 않습니다. 스크립트 자체를 실행하는 셸은 내부 사용을 위한 변수 which도 정의합니다 .PATH

관련 정보