簡體   English   中英

wc:標准輸入:fork +管道+ execlp上的錯誤文件描述符

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM