程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了为什么 execvp() 中的 wc 命令在从 shell 中的管道获取输入时返回错误的结果?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决为什么 execvp() 中的 wc 命令在从 sHell 中的管道获取输入时返回错误的结果??

开发过程中遇到为什么 execvp() 中的 wc 命令在从 sHell 中的管道获取输入时返回错误的结果?的问题如何解决?下面主要结合日常开发的经验,给出你关于为什么 execvp() 中的 wc 命令在从 sHell 中的管道获取输入时返回错误的结果?的解决方法建议,希望对你解决为什么 execvp() 中的 wc 命令在从 sHell 中的管道获取输入时返回错误的结果?有所启发或帮助;

为了学习目的,我正在用 C 编写一个 sHell,我正在尝试允许可变数量的管道。总的来说,它似乎工作得很好。但我注意到 wc 命令有问题。

当我将另一个程序的某些输出通过管道传输到 wc 时,例如 ls | wc,它总是返回
1 3 35 无论我输入什么。当我通过管道输入它们时,其他命令按预期工作。在我正常的 zsh sHell wc 中工作正常。我正在努力寻找问题。我试过在叉子后添加 waitpID 但没有骰子。

这是 @H_381_3@main 函数中的主要 sHell 循环:

while (1) {
        printf("\033[31;1msHell:\033[0m ");

        line = read_cmds();

        if (strstr(line,"|")) {
            // check for pipes first
            pipe_exec(linE);
        } else {
            // we have a single command
            tokens = split(line," \t\r\n");
            if (*tokens != NulL) sHell_exec(tokens);
            free(tokens);
        }
    }

这是循环遍历命令的函数:

voID pipe_exec(char *linE)
{
    int in,status;
    int pipe_no; // keep track of ptr to bring it BACk to free 
    int pfd[2];
    pID_t rc;
    char **cmd,**pipe_cmds;
    
    // split takes a String and splits into array of Strings based on delimiter
    pipe_cmds = split(line,"|"); 

    in = 0;
    pipe_no = 0;
    while (*pipe_cmds) {
        cmd = split(*pipe_cmds," \t\r\n");

        if (pipe(pfd) < 0) perror("pipe");

        make_proc(in,pfd[1],cmd);
        close(pfd[1]);
        in = pfd[0];
        pipe_cmds++; // move ptr ahead one
        pipe_no++;
    }
    // move pointer BACk and free
    pipe_cmds -= pipe_no;
    free(pipe_cmds);

    rc = fork();
    if (rc == 0) {
        if (in != 0) dup2(in,STDIN_fileNO);
        execvp(*cmd,cmd);
    } 
}

然后是上面函数调用的@H_381_3@make_proc函数:

voID make_proc(int in,int out,char **cmd)
{
    pID_t rc;
    rc = fork();
    if (rc  == 0) {
        if (in != STDIN_fileNO) {
            dup2(in,STDIN_fileNO);
            close(in);
        }
        if (out != STDOUT_fileNO) {
            dup2(out,STDOUT_fileNO);
            close(out);
        }
        execvp(*cmd,cmd);
    } 
}

我去掉了一些错误检查以节省空间。 任何帮助表示赞赏!

解决方法

您执行最后一个命令两次并将其第一个实例通过管道传输到第二个。添加如下内容:

    while (*pipe_cmds) { 
        cmd = split(*pipe_cmds," \t\r\n");
        if (!pipe_cmds[1]) {
            break;
        }

        if (pipe(pfd) < 0) perror("pipe");

        make_proc(in,pfd[1],cmd);
        close(pfd[1]);
        in = pfd[0];
        pipe_cmds++; // move ptr ahead one
        pipe_no++;
    }

会阻止不必要的实例,尽管我宁愿稍微重构一下这个函数。

大佬总结

以上是大佬教程为你收集整理的为什么 execvp() 中的 wc 命令在从 shell 中的管道获取输入时返回错误的结果?全部内容,希望文章能够帮你解决为什么 execvp() 中的 wc 命令在从 shell 中的管道获取输入时返回错误的结果?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。