2012-12-09 2 views
3

나는 execvp()를 사용하여 주어진 명령을 실행하는 작은 프로그램을 구현 해왔다. 리디렉션을 사용하지 않을 때 잘 작동하지만 내가 같은 명령을 실행할 때 :execvp() 호출 중 리디렉션이 작동하지 않음

cat file1.txt > redirected.txt 

고양이는 다음과 같은 오류 메시지를 출력하고, 실패 : 나는 짓을했는지

cat: >: No such file or directory 
cat: redirected.txt: No such file or directory 

일부 주위를 파고 난 ' 아마도 execvp()가 쉘에서 실행되지 않기 때문에 리다이렉션을 허용하지 않는다고 생각하기 시작했습니다. 즉, 리디렉션이 발생할 때 수동으로 선택해야하고 포크/exec 코드에서 파이프를 사용하여이 제한을 해결해야합니다. execvp()를 사용하는 것보다 더 좋은 방법이 있습니까?

감사합니다.

답변

7

"주어진 명령을 실행하는 작은 프로그램"은 본질적으로 셸입니다. 쉘을 작성하고 있으므로 원하는 구문으로 리디렉션을 구현하는 것이 좋습니다. > 리디렉션 연산자는 커널의 기능이 아니며 셸 기능입니다.

sh- 스타일 리디렉션을 구현하려면 명령을 구문 분석하고 리디렉션 연산자를 찾은 다음 파일을 열고 입력/출력 설명자에 할당해야합니다. 이것은 전에 전화 execvp 전에 이루어져야합니다. dup2 시스템 호출을 찾습니다.

4

정말 그런 종류의 구문을 사용하려는 경우 system()을 사용할 수 있습니다. 언급했듯이 리다이렉션과 와일드 카드 확장과 다른 많은 것들은 Unix 계열 시스템에서 쉘에 의해 처리됩니다.

int kidpid; 
int fd = open("redirected.txt", O_WRONLY|O_TRUNC|O_CREAT, 0644); 
if (fd < 0) { perror("open"); abort(); } 
switch (kidpid = fork()) { 
    case -1: perror("fork"); abort(); 
    case 0: 
    if (dup2(fd, 1) < 0) { perror("dup2"); abort(); } 
    close(fd); 
    execvp(cmd, args); perror("execvp"); abort(); 
    default: 
    close(fd); 
    /* do whatever the parent wants to do. */ 
} 
+0

'fd' (또는 _set_ close-on-exec 플래그)를 닫아야합니다. 그대로, 프로세스는 여분의 열린 파일 디스크립터를 얻는다. 여기서 무서운 것은 아니지만 다른 맥락에서는 문제가 될 수 있습니다. –

+0

@JonathanLeffler : 좋은 소식입니다. 마지막에 거짓 노트를 제거하고 자식에서 close()를 추가하고 dup2()에서 오류 검사를 수정했습니다. – tmyklebu

3

그것은 할 수있는 쉬운 일이 보인다 같은 :

execlp("/bin/sh", "/bin/sh", "-c", "cat file1.txt > redirected.txt", (char *)NULL); 

당신은 execvp과 같은 작업을 수행 할 수 있습니다

포크와 함께 할 수있는 방법은 다음과 같이 보입니다.

+0

추가 프로세스가 발생하지 않도록 명령에서 "cat"앞에 "exec"를 추가 할 수 있습니다. –

+0

OP의 임무는 교육적 목적을 위해 셸 사용을 피하기 위해 (높은 수준의 '시스템'대신)'execvp '를 사용해야합니다. :) – user4815162342

관련 문제