首页 文章

使用printf命令管道

提问于
浏览
1

我在C中创建了历史命令,用于存储和从文件中获取命令 . 现在我试图通过管道运行“头” . 即历史|头-3

为此,我有第一个dup2()stdout来写管道结束 . 然后使用printf打印历史记录(不会在屏幕上显示) . 之后,我重定向stdin以读取该管道和execvp()head命令 . 它正确显示前3行 . 但它仍在等待用户输入 . 我必须通过Ctrl C终止 . 任何想法为什么会发生这种情况 . 甚至我在显示历史后尝试将所有内容都刷回到标准输出中 . 似乎没什么用 .

pid=fork();
if(pid==0){
    if(...first time..){
        if(dup2(fd[1],1)<0){
              printf("Error in Dup!!");
        }
        printHistory();
        for(k = 0;k < totalfds; k++){
              close(fd[k]);
        }
        return;
    }
    if(...second time..){
        if(dup2(fd[0],0)<0){
            printf("Error in Dup!!");
            }
    }   
    ...
    execvp(subcomm[0],subcomm);
    ...
}

1 回答

  • 1

    命令未终止于EOF的常见问题是您没有关闭足够的文件描述符 . 如果 head 命令仍然具有管道打开的写文件描述符,那么它可能会尝试读取并将挂起,因为管道的写入端已打开 - 即使它是 head 进程使其打开并且它将不会写入直到读取返回 .

    此外,你的孩子 printHistory() 应该在完成后做 exit(0) (或者可能是 _exit(0) ) - 不要回来 . 如果它返回,它可能会返回到读循环 . 如果 execvp() 失败,您还应确保退出进程(状态为非零) . 无需检查 execvp()exec*() 函数的其他成员的返回状态 . 如果他们回来,他们就失败了;如果它们成功,原始进程将被新进程替换,并且函数永远不会返回 .

    另外,作为一般性评论,请使用换行符结束您的消息;它有助于确保它们及时出现 . 还要考虑将错误消息发送到 stderr 而不是 stdout .

相关问题