2010-04-17 108 views
8

我想實現一個支持管道的linux shell。我已經完成了簡單的命令,命令在後臺運行,重定向,但管道仍然缺失。管道執行

我已經閱讀了這篇文章並看了一些代碼片段,但仍然無法理清一個可行的解決方案。

我到目前爲止有:

int fd[2]; 

pipe(fd); 

pid_t pid = fork(); 

if (pid == -1) 
    return -1; 

if (pid == 0) 
{ 
    close(fd[1]); //close write to pipe, in child 
    execlp("cat", "cat", "names.txt", NULL); 
} 

else 
{ 
    close(fd[0]); //close read from pipe, in parent 
    execlp("sort", "sort", NULL); 
} 

我是新手程序員,你可能會說,當我編程的東西我不很瞭解,這是很明顯的情況下,我喜歡從一些非常簡單和具體的東西開始,然後從那裏開始構建。

因此,在能夠在管道中實現三個或更多不同的命令之前,我希望能夠計算「ls names.txt | sort」或類似的東西,其中names.txt是一個名稱文件alfabetically無序的。

更新的代碼,但仍然不起作用。

謝謝。

回答

9

您需要更換一個第一封閉newfd孩子的標準輸出與管道的寫入結束,另一個孩子的標準讀物與讀取結束:

if (pid == 0) 
{ 
    close(fd[1]); //close write to pipe, in child 
    dup2(fd[0], STDIN_FILENO); // Replace stdin with the read end of the pipe 
    close(fd[0]); // Don't need another copy of the pipe read end hanging about 
    execlp("cat", "cat", "names.txt", NULL); 
} 
else 
{ 
    close(fd[0]); //close read from pipe, in parent 
    dup2(fd[1], STDOUT_FILENO); // Replace stdout with the write end of the pipe 
    close(fd[1]); // Don't need another copy of the pipe write end hanging about 
    execlp("sort", "sort", NULL); 
} 
4

調查pipe()標準庫調用。這用於創建管道。您當然必須在之前之前完成fork()的部分工作,以便子進程能夠正確地繼承文件描述符。

還要注意的參數的順序,以dup2()

int dup2(int oldfd, int newfd); 

DUP2()使newfd是oldfd的副本,如果必要的話

+0

我已經知道了,只是忘了將管道語句添加到代碼中。你現在建議什麼?謝謝。 – nunos 2010-04-17 19:15:46

+0

我以爲dup2(0,fd [0])正在將應該轉到stdout的內容複製到fd [0],這是進程的輸入。我想那是我想要的,對吧? – nunos 2010-04-17 19:26:34

+0

@nunos:dup2()不執行復制,它複製*文件描述符*。由於fd [0]是新創建的管道一端的fd,因此關閉該管道並沒有多大意義,因爲dup2()會執行此操作。 – unwind 2010-04-17 19:37:38