2016-11-07 8 views
1

私はまだプロセス、パイプ、dup2の新機能を持っているので、私が作成したプログラムの何が間違っているかを知る手助けをしてくれる人がいます。このプログラムはls | wcを実行することになっています。これまでの出力は次のようになります。プロセスを使ってパイプでコマンドを実行する

この出力が得られた後、端末は引き続き入力を受け入れます。 wcがまだ動いているようですが、lsのようなコマンドを(前に他の入力なしで)置くと、lsを実行してシャットダウンします。プログラムの実行中にpsを実行しようとしましたが、bashとps以外のプロセスは表示されませんでした。

を(私はLinuxターミナルでこのプログラムを実行していることは)ここに私のコードです:

#include<stdio.h> 
#include<unistd.h> 
#include<sys/types.h> 
#include<stdlib.h> 
#include<string.h> 
#include<sys/wait.h> 
#include<errno.h> 

int main(int argc, char* argv[]){ 
     pid_t pid; 
     int fd[2]; 
     char com1[1024] = ("ls"); 
     char com2[1024] = ("wc"); 
     pipe(fd); 
     pid = fork(); 
     if(pid == 0){ 
      open(fd[1]); 
      dup2(fd[0],STDOUT_FILENO); 
      close(fd[0]); 
      execlp(com1, com1, NULL); 
        } 
     else { 
      pid = fork(); 
      if (pid == 0){ 
        open(fd[0]); 
        dup2(fd[1],STDIN_FILENO); 
        close(fd[1]); 
        execlp(com2, com2, NULL); 
         } 
      } 
return 0; 
} 

ベア心​​の中でチェックするためのコマンドは(if(pid<0)exit(0);のように)必要とされる場合、私はいくつか知っているが、私は自分のコードを簡素化しようとしました不注意による間違いがないかどうかを確認するために可能な限り ありがとうございます! the pipe manual pageによれば

+0

そのコードはコンパイルさえしていますか?コンパイラが少なくともあなたに警告を鳴らさなければなりません。 'open(fd [0])'(そしてもちろん 'open(fd [1])')という呼び出しは無効で、削除する必要があります。 –

+0

あなたの問題については、[pipe 'マニュアルページ](http://man7.org/linux/man-pages/man2/pipe.2.html)を読むことをお勧めします。ディスクリプタのうち、パイプの読み込み終了と書き込み終了を注意してください。 –

+0

このコードは今までのところエラーなしでコンパイルされましたが、open()コマンドを削除しても同じ出力を得ました –

答えて

0

pipefd[0]はパイプの読み出し側を指します。 pipefd[1]は、パイプの書き込み側を指します。

は今、lsコマンドを呼び出すプロセスを最初の子から、この行を取る:ここ

dup2(fd[0],STDOUT_FILENO); 

あなたは出力が書き込まれる場所、すなわち、STDOUT_FILENOにパイプの終わりを読んで複製します。それをやめて少し考えてみると、fd[0]のような読み取り専用のファイル記述子にはどうやって書き込みますか?

は、パイプの標準入力の末尾にと書かれている他の子プロセスと同じです。

解決策は簡単です:複製するディスクリプタの場所を入れ替えます。最初の子プロセスにはfd[1]、2番目の子プロセスにはfd[0]を使用します。

dup2(fd[1],STDOUT_FILENO); 
close(fd[1]); 
execlp(com1, com1, NULL); 

そして、あなたはwcコマンドを呼び出す2番目の子プロセスで:あなたはlsコマンドを呼び出す最初の工程で

dup2(fd[0],STDIN_FILENO); 
close(fd[0]); 
execlp(com2, com2, NULL); 
関連する問題