【问题标题】:Strange behavior with Child process子进程的奇怪行为
【发布时间】:2021-07-03 18:19:03
【问题描述】:

我对子进程的行为有疑问。此测试程序的目的是使用管道运行 Linux 命令echo Hello | wc

我的命令不起作用,结果是调用了错误的 c-string。

预期的输出是:

command 0
echo
command 1
wc

但是,我得到:

command 0
echo 
command 1
Hello

当我注释掉时,我只会得到预期的输出 execvp(),当子进程没有退出时。

这里是测试函数:

int test(pid_t id[])
{
    int i;
    int pipefd[2];

    char *cat_args[] = {"echo","Hello", NULL};
    char *grep_args[] = {"wc", NULL};
    char **arr[] = {cat_args,grep_args};

    // make a pipe 
    pipe(pipefd);

    for(i = 0; i < 2; i++){
        id[i] = fork();

        if (id[i] == -1){
            printf("Unable to create child process");
            fprintf(stderr,"fork() failed to spawn child process");
            exit(1);
        }
        else if (id[i] == 0){
            printf("command ");
            printf("%d\n",i);
            
            if (i == 0){
                dup2(pipefd[0],STDIN_FILENO);
            }
            else if (i == 1){
                dup2(pipefd[1],STDOUT_FILENO);
            }
            // Close pipes for child processes
            close(pipefd[0]);
            close(pipefd[1]);

            printf("%s\n",*arr[i]);
            //To simply and simulate problem, can replace execvp() with exit(0);
            execvp(*arr[i],arr[i]);
        }
    }
    // Close pipes of parent process    close(pipefd[0]);
    close(pipefd[1]);
    return 0;
}

这里是主要功能:

int main(int argc, char **argv)
{ 
    pid_t id[2];
    test(id);

    int status;
    
    waitpid(id[0],&status,0); 
    waitpid(id[1],&status,0); 
    return 0;
}

【问题讨论】:

标签: c linux shell pipe execvp


【解决方案1】:

printf 写入标准输出,因此它受您的dup2(pipefd[1],STDOUT_FILENO); 影响,因此进入管道而不是屏幕。

您应该将诊断消息写入标准错误:

fprintf(stderr, "%s\n", *arr[i]);

您之所以看到Hello,是因为这是您的反向管道的输出。

wc | echo Hello

如果你想显示wc 输出1 1 6,你应该翻转它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2011-03-18
    相关资源
    最近更新 更多