2017-01-05 1 views
1

안녕하세요, 저는이 코드가 실패한 부분을 이해하는 데 문제가 있습니다. execvpe (grep)가 실행되는 경우에는 실패합니다 (Console : "Grep Error").실행하는 두 명의 어린이 ls -la | grep using pipes

을 Heres 코드 :

int main(int argc, char *argv[]){ 

    printf("filter.c\n"); 

    int fd[2]; 
    pid_t ls,grep; 


    if(argc<3){ 
    printf("Bitte 2 Argumente angeben <Verzeichnis> <Suchmuster>");  
    exit(-1); 
    } 

    char verzeichnis[256]; 
    char suchmuster [256]; 
    char kind  [256]; 

    strcpy(verzeichnis,argv[1]); 
    strcpy(suchmuster ,argv[2]); 

    if(pipe(fd)<0){ 
     printf("Pipe fehlgeschlagen\n"); 
     return -1; 
    } 

    if((ls=fork())==-1){ 
    //fehler 
    printf("Fork ls fehlgeschlagen\n"); 
    exit(-1); 
    } else if(ls==0){ 
    //kind 
    printf("\nChild1 laueft(ls)\n"); 
    if(dup2(fd[1],STDOUT_FILENO)==-1){//dupliziert fd[1] 
     printf("Dup failed(ls)\n"); 
     return -1; 
    } 

     close(fd[0]); 
     close(fd[1]); 


     char *argu[]={"-la",verzeichnis,NULL}; 
     if(execvpe("bin/ls",argu,NULL)==-1){//EXECVE 
      printf("ls error"); 
      return -1; 
     } 
     return -1 } 

    if((grep=fork())==-1){ 
     //fehler 
     printf("Forken von grep fehlgeschlagen\n"); 
     return -1; 
    } else if(grep==0){ 
     //children2 
     printf("Child 2 lauft (grep)\n"); 
     if(dup2(fd[0],STDIN_FILENO)==-1){ 
      printf("dup2 fd[0] fehlgeschlagen\n"); 
      return -1; 
     } 
     close(fd[0]); 
     close(fd[1]); 


     char *argu[]={"bin/grep",suchmuster,NULL};  
     if(execvpe("bin/grep",argu,NULL)==-1){ 
      printf("Grep error"); 
      return -1; 
     } 
     return -1; 
    } 
    close(fd[0]); 
    close(fd[1]); 

    while(wait(NULL)>0);//while() 
    return 0; 


    // exit(0); 
    } 

그래서 내가 거기 추측은 문제 작성 및 또는 파이프로 /부터 읽고 있습니다. 아무도 내 문제를 알고 있습니까? :/

+0

: 따라서 계정으로 모든 것을 촬영하고는 부모 프로세스의 환경 grepls 사본을 줄 괜찮을 것이라고 가정하여

, 이것은 내가 당신의 간부 호출에 제안하는 일반적인 형식입니다 코드가 어디에서 실패했는지 판단하는 데 중요한 정보는 * 실패 *하는 방법입니다. 해결하려는 문제의 성격은 정확히 무엇입니까? –

+0

it "Grep error"를 반환하므로 거기에 있어야합니다 .. – Felix

+1

/디렉토리에서 프로그램을 실행하지 않는 한 grep에 적절한 경로를 추가해야합니다. ''/ bin/grep "' – Gerhardh

답변

1

실행 파일의 지정된 경로에 / 문자가 있으면 검색이 수행되지 않습니다. 이 경우 호출시 필요에 따라 프로세스의 현재 작업 디렉토리와 관련하여 주어진 경로가 해석됩니다. 이는 거의 원하는 것이 아니며 귀하의 사례는 예외처럼 보이지 않습니다. 실제로, 단순한 이름 대신에 바이너리 경로를 지정하려고한다면, exec의 경로 검색 변형에서 어떤 이점도 얻지 못합니다.

또한 execvpe()의 마지막 인수는 NULL로 끝나는 배열의 첫 번째 요소 인 char *에 대한 포인터입니다. pointed-to 배열에는 종결 자 이외의 요소가 없을 수도 있지만 인수 자체가 NULL이되도록 허용 된 문서는 없습니다. 당신이 실제로 exec 된 프로그램에 대한 빈 환경을 지정하려는 경우, 다음 두 execvpe() 호출이 일반적인 형태를 취한다 :

char *argu[] = { "grep", suchmuster, NULL };  
char *env[] = { NULL }; 
if (execvpe("/bin/grep", argu, env) == -1) { 

또한, 빈 환경과 외부 프로세스를 execing하는 것처럼 반드시 잘못되지 의심이다. 이 목적을 위해 나는 많은 이점을 보지 못한다. 그리고 호출 된 프로세스 환경의 사본을 exec'ed 이미지에 제공하는 exec 함수 중 하나를 사용하면 문제를 줄일 수있다. 예를 들어 execvp()은 해당 특성을 갖는 execvpe()에 가장 가까운 것입니다.

또한, exec 인수로 을 사용하는 배열에 프로그램 인수를 채우는 것은 약간 어리석은 것처럼 보입니다. exec의 varargs 변형은이를 수행 할 필요를 회피합니다 (execl() 등).

exec 함수는 오류가 발생했을 때만 반환됩니다. 반환 값을 테스트 할 수 있지만 이러한 함수가 모두 반환되면 반환 값은 항상 -1입니다.

 execl("/bin/grep", "grep", suchmuster, NULL); 
     // an error occurred 
     perror("execing grep"); 
     _Exit(1); 
+0

메신저 실행 중일 경우 execl ("bin/ls", "- la", Verzeichnis, NULL); perror(); 그런 다음 종료합니다 (해당 파일 또는 디렉토리 없음). 필자는 "/ home" "home" "을 시도했습니다." 및 "..". 내가 잘못된 인수를 삽입하고 있습니까? 현재 작업 디렉토리에 하위 폴더가 없습니다. – Felix

+0

@Felix, 당신은'/'을 포함하고 있지만 하나는 시작하지 않는 경로를 제공합니다. 이미 설명했듯이 경로에서 조회하지 않고 현재 작업 디렉토리와 관련하여 해결됩니다. 예를 들어, 작업 디렉토리가'/ home/felix'이라면, exec는'/ home/felix/bin/ls'과 * only *를 찾을 것입니다. 내가 제시 한 모델을 따르십시오. –

+0

감사합니다. 지금 ist working :) – Felix