首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C实现Linux Shell中的管道

问用C实现Linux Shell中的管道
EN

Stack Overflow用户
提问于 2011-11-26 21:01:03
回答 2查看 1.4K关注 0票数 1

我正在尝试实现一个支持多管道的简单shell程序。现在,我的shell可以实现一些简单的内置命令和外部命令。为此,我从命令行获取用户输入,并将每个字符串放在一个char* argv[]中。命令行由空格" "分隔。现在的问题是执行管道。我在这个链接http://www.cs.loyola.edu/~jglenn/702/S2005/Examples/dup2.html中读到了一点关于它的信息。我明白了它是如何工作的。

所以我想到了用"|" strcmp每个管道,当我遇到一个管道时,我就fork一个新的进程。然后,我在char* argv[]中将字符串放在管道之前,在另一个char* argv[]中将管道后面的字符串放在管道之前。这可能适用于1个管道,但如果用户输入多个具有多个管道,使用此方法可能会变得单调乏味。我的主要问题是如何将管道两端的字符串分开。有没有关于如何实现它的想法?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-26 21:08:29

分而治之:

  1. 查找第一个管道参数
  2. 如果找不到管道,请使用stdout作为输出执行数组,并将非管道第一部分和其余部分之间的参数数组作为输出。
  3. 制作管道并使用管道作为输出执行非管道第一部分
  4. 从参数数组中删除非管道第一部分和管道

<代码>H111转到1<代码>H212<代码>G213

由于C数组的语义,第三步非常简单:

代码语言:javascript
复制
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所关心的。

票数 2
EN

Stack Overflow用户

发布于 2011-11-26 21:18:00

您甚至可以通过将管道替换为空字符串(终止argv数组)来重用argv数组。

所以你的数组是这样的:

代码语言:javascript
复制
"a", "b", "|",  "c", "d", "e", "|",  "f", "g", "h", NULL

您可以将其更改为

代码语言:javascript
复制
"a", "b", NULL, "c", "d", "e", NULL, "f", "g", "h", NULL

瞧,这是你的三个命令行:argv,argv+3,argv+7

管道的难点在于设置stdin和stdout文件描述符,而不是命令的实际执行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8278572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档