/bin/sh: 0: sh를 열 수 없습니다.

/bin/sh: 0: sh를 열 수 없습니다.

간단한 C 프로그램을 실행하려고 합니다.

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

extern char** environ;

int main(){
//  execl("/bin/sh","sh","-c","/bin/ls -l",(char *) NULL);
    char* argv[] = {"/bin/sh","sh","-c","/bin/ls", (char*) NULL};
    execve(argv[0], argv, environ);
    return 0;
}

주석 처리된 execl은 잘 작동합니다. 그러나 execve로 동일한 작업을 수행하려고 하면 컴파일러에서 다음 오류를 호출합니다.

/bin/sh: 0: Can't open sh

내가 여기서 뭘 잘못하고 있는 걸까?

답변1

char* argv[] = {"/bin/sh","sh","-c","/bin/ls", (char*) NULL};
execve(argv[0], argv, environ);

argv[0]( )를 두 번 사용합니다 /bin/sh. 한 번은 첫 번째 인수로 사용 execve()하고 한 번은 두 번째 인수로 전달된 배열의 일부로 사용합니다. 이것은 호출 execl()에서 일어나는 일이 아니며 /bin/sh첫 번째 매개변수(프로그램 파일)만 있습니다.

따라서 execve()파일을 실행하여 /bin/sh프로그램 이름(0번째 인수) /bin/sh과 일반 인수 sh, -c, 를 제공합니다 /bin/ls. 를 호출하는 것과 거의 같습니다 execl("/bin/sh", "/bin/sh", "sh", "-c", "/bin/ls", (char*) NULL). 또는 쉘 명령줄에서:

$ /bin/sh sh -c /bin/ls
/bin/sh: 0: Can't open sh

이는 쉘이 현재 디렉토리에서 호출된 스크립트를 실행하도록 지시하며 sh스크립트가 존재하지 않으면 Dash는 오류 메시지를 표시합니다. 0은 명령줄 인수의 줄 번호일 수 있습니다. (Bash는 비슷하지만 다른 오류 메시지를 제공하며 스크립트도 찾고 있는 것 같습니다 PATH. 표준에서 PATH여기서 사용에 대해 언급하는 것이 확실하지 않습니다.)

당신은 이것을 할 수 있습니다

char *program = "/bin/sh";
char *argv[] = {"sh", "-c", "/bin/ls", NULL};
execve(program, argv, environ);

아니면 어쩌면

char *argv[] = {"/bin/sh", "sh", "-c", "/bin/ls", NULL};
execve(argv[0], argv + 1, environ);

관련 정보