簡體   English   中英

重定向子進程中的標准輸出是否也為父進程執行此操作?

[英]Does redirecting standard output in a child process do so for the parent process as well?

我正在星期二學習OS考試。 為了准備,我試圖通過C程序模擬命令行管道。

該計划非常簡單。 我制作一個管道,然后分叉一個子進程。

子進程將標准輸出重定向到管道的寫入端,關閉管道的文件描述符,然后執行命令(在本例中為ls )。

父進程等待子進程退出,將標准輸入重定向到管道的讀取端,關閉管道的文件描述符,然后執行命令(在本例中為grep 'school' )。

當我使用ls | grep 'school'通過命令行執行命令時 ls | grep 'school'有一行說“school”打印到標准輸出,這是有道理的,因為目錄中有一個目錄,我正在運行該命名的程序。

當我運行我創建的程序時,我沒有收到任何錯誤消息,但它不會產生任何輸出。

我唯一可以想到的就是阻止它工作的是,在子進程中重定向標准輸出會以某種方式影響父進程命令的輸出,但我幾乎肯定不應該這樣。

這是代碼:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main() {
    int fds[2];
    int pipe_val, close_val, write_val, dup_val, status;
    pid_t pid;
    char *error;

    pipe_val = pipe(fds);
    if (pipe_val) {
        fprintf(stderr, "Failed to prepare pipe.\n");
        return -1;
    }
    pid = fork();
    if (pid == -1) {
        fprintf(stderr, "Failed to fork a child process.\n");
        return -1;
    } else if (pid == 0) {
        dup_val = dup2(fds[1], STDOUT_FILENO);
        if (dup_val) {
            error = strerror(errno);
            fprintf(stderr, "Failed to redirect standard output in child process because %s\n", error);
            exit(1);
        }
        close_val = close(fds[0]);
        if (close_val) {
            fprintf(stderr, "Failed to close read-end of pipe in child process.\n");
            exit(1);
        }
        close_val = close(fds[1]);
        if (close_val) {
            fprintf(stderr, "Failed to close write-end of pipe in child process.\n");
            exit(1);
        }
        execl("/bin/ls", "ls", NULL);
        fprintf(stderr, "Failed to execute command in child process.\n");
        exit(1);
    } else {
        wait(&status);
        dup_val = dup2(fds[0], STDIN_FILENO);
        if (dup_val) {
           error = strerror(errno);
           fprintf(stderr, "Failed to redirect standard input in parent process because %s.\n", error);
            return -1;
        }
        close_val = close(fds[0]);
        if (close_val) {
            fprintf(stderr, "Failed to close read-end of the pipe in the parent process.\n");
            return -1;
        }
        close_val = close(fds[1]);
        if (close_val) {
            fprintf(stderr, "Failed to close write-end of the pipe in the parent process.\n");
            return -1;
        }
        execl("/bin/grep", "grep", "school", NULL);
        fprintf(stderr, "Failed to execute the command in the parent process.\n");
        return -1;
    }
}

您的第一個問題是您沒有為您正在使用的功能包含所有必需的標題。 strerror需要<string.h>並且wait需要<sys/wait.h>

如果您正在使用gcc -Wall進行編譯,請始終使用gcc -Wall並閱讀警告。 在這種情況下,它會抱怨隱含的strerror聲明。

因為未聲明strerror ,編譯器會假定它返回一個int ,這是錯誤的。 如果您在64位Linux x86上運行該程序,則intstrerror返回的指針的大小不同 當你將strerror的結果以%s格式傳遞給fprintf時,這會成為一個致命的問題,因為指針被誤解為int,然后轉換回指針,最后是偽造的值。 fprintf錯誤,你永遠不會看到你的錯誤信息。

包含正確的標題,您將看到一條錯誤消息,該消息將引導您解決下一個需要解決的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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