간단한 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);