[英]wc: standard input: Bad file descriptor on fork + pipe + execlp
我知道這是一個簡單的練習,但是我遇到了麻煩。 我正在嘗試模仿:
grep arg1 arg2 | wc -l
我收到以下錯誤:“ wc:標准輸入:執行時文件描述符錯誤”。 這是我的代碼:
int main(int argc, char *argv[])
{
if (argc != 3) usage();
int pd[2]; //Pipe descriptor
pipe(pd);
int pid = fork();
if (pid < 0) perror("Something failed on trying to create a child process!\n");
else if (pid == 0) { //Child
dup2(pd[1], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
} else { //Parent
dup2(pd[0], 1);
close(pd[0]);
close(pd[1]);
execlp("grep", "grep", argv[1], argv[2], (char *)NULL);
}
}
可能是什么問題?
你有:
else if (pid == 0) { //Child
dup2(pd[1], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
}
你需要:
else if (pid == 0) { //Child
dup2(pd[0], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
fprintf(stderr, "Failed to execute 'wc'\n");
exit(1);
}
關鍵的更改是dup2()
; 您的代碼會將管道的寫入端復制到孩子的標准輸入中,這不是幸福的秘訣。 修改后的代碼將管道的讀取端復制到孩子的標准輸入中。 容易記住哪個是:stdin是文件描述符0,而該對中的管道描述符0是輸入描述符(管道的讀取端),而stdout是文件描述符1,而該對中的管道描述符1是輸出描述符。 (寫出管道的末端)。
您需要在“父代”代碼中進行相反的更改。
當wc
嘗試從僅開放用於寫入的文件描述符中讀取時,會出現此錯誤。
請注意,如果execlp()
或exec*()
函數系列的任何其他成員返回,則它將失敗。 重要的是,通常通過報告有關標准錯誤的問題並退出來處理該錯誤。 在exec*()
操作之后沒有語句很少是正確的。
如我所見,您嘗試復制終端命令“ wc -l | grep某些東西”。
問題是您沒有向wc提供輸入。 wc -l命令需要一個輸入,它應該為其行數。 嘗試類似:
execlp("wc", "wc", "-l", "somefile.txt", (char *)NULL);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.