2017-01-05 11 views
1

こんにちは、私は、このコードが失敗する箇所を理解している問題があります。 execvpe(grep)が実行されていると、おそらく失敗します(コンソール: "Grep Error")。実行する2人の子供ls -la | grep using pipes

相続コード:

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

あなたのコードがどこで*失敗したかを判断する上で重要な情報は、*失敗*する方法です。解決しようとしている問題の性質はどういうものですか? –

+0

it "Grep error"を返すので、そこにある必要があります。 – Felix

+1

/ディレクトリからプログラムを実行しない限り、grepへの適切なパスを追加する必要があります。 ''/bin/grep "'を試してください – Gerhardh

答えて

1

実行可能ファイルへの指定されたパスに/文字が含まれている場合、検索は実行されません。この場合、必要に応じて、呼び出し時のプロセスの現在の作業ディレクトリを基準にして、指定されたパスが解決されます。それはまれにあなたが望むものであり、あなたのケースは例外のようには見えません。さらに、単純な名前ではなく、バイナリへのパスを指定する場合、execのパス検索バリアントから何の利点も得られません。

また、execvpe()の最後の引数は、NULL終了型配列char *の最初の要素へのポインタであると考えられます。指し示された配列にはターミネータ以外の要素はないかもしれませんが、引数そのものがNULLであることを示す文書はありません。あなたは確かにexec'edプログラムのための空の環境を指定したい場合は、その後、両方のexecvpe()呼び出しは、この一般的な形式をとる必要があります。

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

さらに、空の環境で外部プロセスをexecingするものの、必ずしも間違っていない、疑わしいです。この目的のために私は多くの利点を見ていないし、実行されるイメージに呼び出しプロセスの環境のコピーを提供するだけのexec関数の1つを使用することで、いくつかの問題を省くことができます。 execvp()は、例えば、その特性を有するexecvpe()に最も近いものとなります。

さらに、プログラム引数を、 execコール用に使用する配列にパックするのは少しばかげているようです。 execのvarargsの亜種は、それを行う必要を回避します(execl()など)。

exec関数はエラー時にのみ返ります。 戻り値をテストしますが、これらの関数がまったく返されない場合、戻り値は常に-1になります。

ので、アカウントにすべてのことを考えると、親プロセスの環境のgreplsコピーを与えるために、OKだろうと仮定し、これは私があなたのexecコールに示唆している一般的な形式です:

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

実行中の場合 execl( "bin/ls"、 " - la"、Verzeichnis、NULL); perror(); それからそこから出ます(このようなファイルやディレクトリはありません)。 Iveは "/ home" "home" "を試しました。"と ".."。間違った引数を挿入していますか?現在の作業ディレクトリにサブフォルダはありません – Felix

+0

@Felix、あなたは '/'を含むパスを与えますが、最初はそれではありません。これは、既に説明したように、現在の作業ディレクトリに対して相対パスで検索されずに解決されます。たとえば、作業ディレクトリが '/ home/felix'の場合、execは'/home/felix/bin/ls'を探し、* only *を探します。私が提示したモデルに従ってください。 –

+0

ありがとう、今ist作業:) – Felix

関連する問題