我正在尝试实现一个支持多个管道的简单shell程序。现在我的shell可以实现一些简单的内置命令和外部命令。我通过从命令行获取用户输入来完成此操作,命令行由空格" "
分隔并将每个字符串放在char* argv[]
中。现在的问题是执行管道。我在这个链接http://www.cs.loyola.edu/~jglenn/702/S2005/Examples/dup2.html中读了一篇关于它的文章。我明白它是如何运作的。
所以我考虑strcmp
每个argv[i]
和"|"
,当我遇到管道时,我fork
一个新流程。然后我将字符串放在管道前面char* argv[]
中,将管道后面的字符串放在另一个char* argv[]
中。这可能适用于1个管道但如果用户输入的多个管道有多个管道,则此方法可能会变得繁琐。我的主要问题是分离管道两端的琴弦。关于如何实现它的任何想法?感谢。
答案 0 :(得分:2)
分而治之:
由于C数组语义,第3步非常简单:
char **arguments;
int pipe_position = /* for example: */ 5;
assert( strcmp( arguments[pipe_position], "|" ) == 0 );
arguments[pipe_position] = NULL;
char **my_arguments = arguments;
arguments = arguments + pipe_position + 1;
然后my_arguments是一个长度为pipe_position
的数组,其中包含第一个参数,而arguments
是一个长度为argc - pipe_position - 1
的数组,其中包含其余参数。您可以毫无问题地将这些指针提供给execvp。是的,他们指向同一块记忆,但这不是execvp的关注。
答案 1 :(得分:2)
你甚至可以通过用空字符串替换管道来重用argv数组(终止argv数组)。
所以你的数组是这样的:
"a", "b", "|", "c", "d", "e", "|", "f", "g", "h", NULL
你改成
"a", "b", NULL, "c", "d", "e", NULL, "f", "g", "h", NULL
瞧,这是您的三个命令行:argv
,argv+3
,argv+7
管道的困难部分是设置stdin和stdout文件描述符,而不是命令的实际执行。