2016-09-08 4 views
0

私はbashシェル(/ bin/sh)にコマンドを送受信するプログラムを書こうとしています。 bashシェルのラッパープログラムのように。だから、私はstdin "cd〜/ Desktop"に書き込んで、 "ls"をもう一度書くと、デスクトップにファイルのリストが表示されます。私はそれを動作させることはできません。このコードの2番目の書き込みコマンドでは、私がstdinに書き込んだものをエコーバックします。私もpopen()を使ってみましたが、これは出力のみを提供し、標準入力に書き込むことはできません。誰かがこの問題を解決するのを助けてくれますか?おかげbashインタプリタのstdin/outを読み書きします。linux、fork-execl

void main() 
{ 
    // Create a pipe and fork 
    // 
    int fd[2]; 
    int p = pipe(fd); 
    pid_t pid = fork(); 

    if (pid > 0) 
    { 
     // Read from the pipe and output the result 
     // 
     //close(fd[1]); 
     char buf[1024] = { 0 }; 

     read(fd[0], buf, sizeof(buf)); 

     printf("1 - %s\n", buf); 

     write (fd[1], "ifconfig", strlen ("ifconfig")); 

     // problem is here, read is returning echo'd bytes from write() 

     read(fd[0], buf, sizeof(buf)); 

     printf("2 - %s\n", buf);  


     // Wait for child to terminate 
     int status; 
     wait(&status); 
    } 
    else if (pid == 0) 
    { 
     // Redirect stdout and stderr to the pipe and execute the shell 
     // command 
     // 
     dup2(fd[0], STDIN_FILENO); 
     dup2(fd[1], STDOUT_FILENO); 
     dup2(fd[1], STDERR_FILENO); 
     //close(fd[0]); 
     execl("/bin/sh", "exec sh", "-c", "ls", (char*) NULL); 
    } 

}

EDIT - 第一の答えあたりの更新されたコードは、今()パイプがあることを覚えておいてください

void main() 
{ 
    // Create a pipe and fork 
    // 
    int fd[2]; 

int ChildToParent[2], ParentToChild[2]; 



    pipe (ParentToChild); 
pipe (ChildToParent); 

    pid_t pid = fork(); 

    if (pid > 0) 
    { 
     // In parent process 

     // Read the output of the child from child_to_parent[0] 
     // We don't need child_to_parent[1] so close it 
     close(ChildToParent[1]); 

     // Write output to the child using parent_to_child[1] 
     // We don't need parent_to_child[0] so close it 
     close(ParentToChild[0]); 

     // Read from and write to the child process... 
     char buf[1024] = { 0 }; 

     read(ChildToParent[0], buf, sizeof(buf)); 
    printf("1 - %s\n", buf); 


    write(ParentToChild[1], "whoami", strlen ("whoami")); 

    memset (buf, 0, 1024); 

    // this call to read returns nothing 
    read(ChildToParent[0], buf, sizeof(buf)); 
    printf("2 - %s\n", buf); 



    } 
    else if (pid == 0) 
    { 
     // Redirect stdout and stderr to the pipe and execute the shell 
     // command 
     // 
    // child_to_parent[1] is were we write output, it's the 
     // new standard output, child_to_parent[0] can be closed 
     dup2 (ChildToParent[1], STDOUT_FILENO); 
     close(ChildToParent[0]); 

     // parent_to_child[0] is where we read input from, it's the 
     // new standard input, parent_to_child[1] can be closed 
     dup2 (ParentToChild[0], STDIN_FILENO); 
     close(ParentToChild[1]); 

     //close(fd[0]); 
     execl("/bin/sh", "exec sh", "-c", "ls", (char*) NULL); 
    } 

}

+0

は、次の2つのパイプを必要としています。 –

+0

それでは、 "dup2(fd [0]、STDIN_FILENO); dup2(fd [1]、STDOUT_FILENO);"のためですか?コードで何を話しているのか説明できますか? – shelly3783

答えて

2

を呼び出す第二の読み取りからの出力はありません一方向通信ストリーム。 2つのプロセス間の双方向通信には使用できません。そのためには、それぞれの方向に1本ずつ2本のパイプが必要です。

はおそらく、この単純な例のようなもの:に書き込むための親プロセスから読み込むための子プロセスの一つ、と反対方向のための別のパイプ:

// Pipe for the child process to write to the parent process 
int child_to_parent[2]; 

// Pipe for the parent process to write to the child process 
int parent_to_child[2]; 

// Create the TWO pipes 
pipe(child_to_parent); 
pipe(parent_to_child); 

pid_t pid = fork(); 
if (pid > 0) 
{ 
    // In parent process 

    // Read the output of the child from child_to_parent[0] 
    // We don't need child_to_parent[1] so close it 
    close(child_to_parent[1]); 

    // Write output to the child using parent_to_child[1] 
    // We don't need parent_to_child[0] so close it 
    close(parent_to_child[0]); 

    // Read from and write to the child process... 
} 
else if (pid == 0) 
{ 
    // In child process 

    // child_to_parent[1] is were we write output, it's the 
    // new standard output, child_to_parent[0] can be closed 
    dup2(child_to_parent[1], STDOUT_FILENO); 
    close(child_to_parent[0]); 

    // parent_to_child[0] is where we read input from, it's the 
    // new standard input, parent_to_child[1] can be closed 
    dup2(parent_to_child[0], STDIN_FILENO); 
    close(parent_to_child[1]); 

    // Do whatever the child is supposed to do 
} 
+0

ええと、私はこれを試してみるつもりですが、元のコードからclose()を呼び出すだけです。申し訳ありませんが、これはまだ分かりませんが、特にこれはコンパイルされませんが、私は試してみてください... – shelly3783

+0

正確に私がどこから読み込み()と書き込み()を行うべきかを教えてください。 – shelly3783

+0

@ shelly3783あなたのコードと比較して、私の例のパイプの数を数えてください...あなたはコメントを読んだことがありますか?パイプの2つの異なる変数に気付いた? –

関連する問題