我正在尝试在Linux上用C语言实现一个shell。我正在研究这个项目,要求在C中创建一个shell,从创建一个非常基本的(myShell)开始,逐步深入。首先,我必须使用像
这样的简单命令创建一个shellLS,PWD,回声,日期,时间
(抽壳)。
之后,我的Shell必须进行改进,以便它可以对文件(例如txt)(shell2)进行排序,并且随着它的继续,我必须通过开发它来做更多的事情,并让它执行像
这样的命令sort -r,sort -u。(shell3)。
直到第3个shell,我正在处理重定向,一切进展顺利。
现在对于第4个shell,我应该让它用管道运行命令,例如ls -l / home / |排序> out.txt。我已设法使命令工作,out.txt文件成功创建并相应地进行排序。在我的代码上有一个while(),所以在我给shell的每个命令之后它要求下一个等等。但是当给出上面的示例命令并且使用管道时,程序停止。终端没有显示" myShell4>"但桌面$和它基本上退出了shell。给它简单的命令,比如" ls -l" ,不使用管道,工作完美,所以从中我意识到问题出在管道中,他们阻止我的程序循环。
我的代码中发生这种情况的部分:
//CHILD
dup2(pipefd[1],1);
close(pipefd[0]);
execute(cmd,path,argm);
//PARENT
dup2(pipefd[0],0);
close(pipefd[1]);
execlp(cmd2,cmd2,NULL);
有什么想法?提前谢谢!
答案 0 :(得分:1)
父母是外壳,对吗?不要在那里执行;为管道的两端创建子节点并在父节点中等待它们。如果这样做,shell将被替换,并且在命令结束后不再运行。
以下是两个命令之间管道的一些伪代码:
int pipefd[2];
pipe (pipefd);
// child for first command
if (fork () == 0) {
// setup in redirection if any
...
// setup out redirection
close (pipefd[0]);
dup2 (pipefd[1], STDOUT_FILENO);
...
exec (cmd1, ...);
exit (1);
}
// child for second command
if (fork () == 0) {
// setup in redirection
close (pipefd[1]);
dup2 (pipefd[0], STDIN_FILENO);
// setup out redirection if any
dup2 (output_file_fd, STDOUT_FILENO);
exec (cmd2, ...);
exit (1);
}
close (pipefd[0]);
close (pipefd[1]);
// parent waits and then restarts the loop
wait (NULL);
wait (NULL);
对于通过管道连接的两个以上命令的列表,事情变得更加复杂。