使用printf命令管道

时间:2013-09-12 22:46:12

标签: c shell unix

我在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 个答案:

答案 0 :(得分:1)

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

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

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