2014-12-02 3 views
0

По какой-то причине я не могу понять это правильно, я хочу называть «ls -l» и «tail -n 2» по конвейеру, чтобы последние два файла в списке файлов отображали , Вот код:Использование простого конвейера unix

int pipefd[2]; 
pipe(pipefd); 
int id = fork(); 

if(id == 0) 
{ 
    dup2(pipefd[1], 1); 
    close(pipefd[1]); 
    execvp("ls", (char*[]){"ls", "-l", NULL}); 
} 
else 
{ 
    dup2(pipefd[0], 0); 
    execvp("tail", (char*[]){"tail", "-n", "2", NULL}); 
    waitpid(id, NULL, 0); 
    close(pipefd[0]); 
} 

return 0; 

В чем проблема в следующем коде? Я чувствую, что у меня есть недоразумение здесь, я искал много, и никакого ответа не был найден в интернете ...

ответ

1

Называя это:

dup2(pipefd[1], 1); close(pipefd[1]);

в дочернем процессе вы закрываете уже закрытые pipefd[1], поэтому close(pipefd[1]); не влияет. Вы также должны закрыть pipefd[0] в дочернем процессе. То же самое относится к родительскому процессу. Таким образом, ваш код должен быть изменен, как показано ниже:

int pipefd[2]; 
pipe(pipefd); 
int id = fork(); 

if(id == 0) 
{ 
    dup2(pipefd[1], 1); 
    close(pipefd[0]); 
    execvp("ls", (char*[]){"ls", "-l", NULL}); 
} 
else 
{ 
    dup2(pipefd[0], 0); 
    close(pipefd[1]); 
    execvp("tail", (char*[]){"tail", "-n", "2", NULL}); 
    waitpid(id, NULL, 0); 
} 
+0

Большое спасибо! Работая, я понял свою проблему. – Jonathan

+0

Как насчет 3 процессов, кстати? – Jonathan

+0

Ну, идея остается прежней. Если вы скажете мне, что вы хотите сделать с этими 3 процессами, я постараюсь помочь. –

0

Заменить tail с cat, и Вы увидите список файлов, передаются и печатается cat, но EOF не достигнуто. Вам необходимо закрыть неиспользуемые дескрипторы pipefd:

Обратите внимание, что waitpid в этой программе достигается только в случае, если execvp из tail не работает.

Исправлен код:

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

int main(){ 
    int pipefd[2]; 
    pipe(pipefd); 
    int id = fork(); 

    if(id == 0) 
    { 
     dup2(pipefd[1], 1); 
     close(pipefd[0]); 
     close(pipefd[1]); 
     printf("child fd = %d\n", fileno(stdout)); 
     execvp("ls", (char*[]){"ls", "-l", NULL}); 
    } 
    else 
    { 
     dup2(pipefd[0], 0); 
     close(pipefd[0]); 
     close(pipefd[1]); 
     execvp("tail", (char*[]){"tail", "-n", "2", NULL}); 
/* execvp("cat", (char*[]){"cat", NULL});*/ 
     waitpid(id, NULL, 0); 
    } 

    return 0; 
} 
+0

Согласно документации, 'dup2' dosn't близко оригинальный дескриптор, оба дескрипторы могут использоваться (но относятся к одному файлу) после успешного вызова. – kestasx

0

Попробуйте (обратите внимание на дополнительные закрывается) ...:

int pipefd[2]; 
    pipe(pipefd); 

    int id = fork(); 

    if(id == 0) 
    { 
     dup2(pipefd[1], 1); 
     close(pipefd[1]); 
     close(pipefd[0]); 
     execvp("ls", (char*[]){"ls", "-l", NULL}); 
    } 
    else 
    { 
     dup2(pipefd[0], 0); 
     close(pipefd[0]); 
     close(pipefd[1]); 
     execvp("tail", (char*[]){"tail", "-n", "2", NULL}); 
     waitpid(id, NULL, 0); 
    } 

    return 0; 
Смежные вопросы