4

私はLinuxなどにとても慣れていません。スクリプトを機能させることができません。tr関数の実行時にプログラムが中断されていると推測しています。

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{

int pdesc[2];
pipe(pdesc);

int a = fork();

if (a == 0) // child
    {

    dup2(pdesc[1],1); // chaning std_out to pipes_out
    execlp("ls", "ls", "-l", "-a", NULL);

    }
else       //parent
    {
    wait();
    int file1 = open("file.txt", O_WRONLY|O_CREAT|O_TRUNC,0777);
    dup2(pdesc[0], 0); // chaning std_in to pipes_in
    dup2(file1, 1); // chaning std_out to file's stream
    execlp("tr", "tr", "a-z", "A-Z", NULL);
    }



return 0;
}
4

1 に答える 1

6

古典的な間違いなので、良い質問です。

親と子の両方で未使用のパイプファイル記述子を閉じる必要があります。

パイプから読み取るプロセスには(それ自体)開いたパイプ書き込み端があるため、パイプが完全に閉じられることはなく、EOFを提供することはありません。

また、wait(2)がデッドロックを引き起こしており、プログラムにが含まれておらず、<sys/wait.h>toの呼び出しにwait(2)必要な引数がありません。シェルは親が終了するのを待機しますが、子は待機しないため、実際には、wait(2)ここのどこかに呼び出しがあると便利です。しかし、現在の2プロセス設計では、親の後に制御できないため、それを配置する場所がありませんexeclp(2)。これを修正する1つの方法は、親fork()を再度使用し、元のPIDに、すべての子が終了するまでループ内でwait(2)以外の処理を行わないようにすることです。

これが動作中のバージョンです。出力ファイルモードへの変更にも注意してください。

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
int pdesc[2];

    pipe(pdesc);

    int a = fork();

    if (a == 0) { // child
        dup2(pdesc[1],1); // chaining std_out to pipes_out
        close(pdesc[1]);
        close(pdesc[0]);
        execlp("ls", "ls", "-l", "-a", NULL);
    } else {      //parent
        int file1 = open("file.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
        dup2(pdesc[0], 0); // chaning std_in to pipes_in
        dup2(file1, 1); // chaning std_out to file's stream
        close(pdesc[0]);
        close(pdesc[1]);
        close(file1);
        execlp("tr", "tr", "a-z", "A-Z", NULL);
    }
    return 0;
}
于 2012-11-03T17:28:11.307 に答える