【问题标题】:Implemeting pipes in Linux Shell with C使用 C 在 Linux Shell 中实现管道
【发布时间】:2011-11-26 13:01:03
【问题描述】:

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

所以我想到了strcmp 每个argv[i] 和"|",当我遇到管道时,我fork 一个新进程。然后我将管道前的琴弦放入char* argv[],将管道后的琴弦放入另一个char* argv[]。这可能适用于 1 个管道,但如果用户输入多个有多个管道,则使用此方法可能会变得乏味。我的主要问题是分离管道两端的琴弦。关于如何实施它的任何想法?谢谢。

【问题讨论】:

    标签: c linux shell char pipe


    【解决方案1】:

    分而治之:

    1. 找到第一个管道参数
    2. 如果未找到管道,则以 stdout 作为输出执行数组并终止。
    3. 在非管道的第一部分和其余部分之间划分参数数组。
    4. 制作一个管道并以管道作为输出执行非管道第一部分
    5. 从参数数组中删除非管道第一部分和管道
    6. 转到 1

    由于 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 关心的问题。

    【讨论】:

    • 感谢您的回复。 3号是我的问题所在。如何将char * [] 类型的参数数组划分为char * [] 的另一个数组?如果我有多个管道,是否必须为遇到的每个管道连续创建一个数组?我正在使用 execvp 来执行参数数组。
    • 我想我掌握了一点。所以这个分治法应该做while arguments[i] != NULL。我对吗?我也应该这样调用 execvp:execvp(*my_arguments, my_arguments) 而不是execvp(*my_arguments, arguments)?
    • 感谢您的帮助。这真的很有帮助。
    【解决方案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

    管道的难点在于设置标准输入和标准输出文件描述符,而不是命令的实际执行。

    【讨论】:

    • 感谢您的回复。我想我有点明白了。我使用 execvp 来执行我的命令。那么我是否必须为每个以 NULL 结尾的字符串创建一个单独的数组?例如array1 = "a", "b", NULLarray2="c", "d", "e", NULLarray3= "f", "g", "h", NULL
    • 不,你没有。您现在可以使用子数组,因为它们以 NULL 结尾。
    • 感谢您的帮助。帮我澄清了一些事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    相关资源
    最近更新 更多