【问题标题】:C UNIX Shell execvp Echoing QuotesC UNIX Shell execvp 引用引用
【发布时间】:2012-10-14 20:26:14
【问题描述】:

所以我正在用 C 编写一个基本的 UNIX minishell。一切都进行得很顺利,但是我最近重新设计了它从控制台获取的原始字符串解析参数的方式。这是它解析方式的一个示例:

$> echo HELLO "" WORLD!
HELLO "" WORLD!

参数数组如下所示:[echo0, HELLO0, ""0, WORLD!0]

我是这样通过的:

execvp(args[0], args);

但是,echo 应该省略引号,并且如您所见,它会将它们打印出来。由于 echo 在我的情况下不是内置命令,因此我无法自定义它的打印方式。有谁知道为什么会发生这种情况?我想省略双引号,但包括所有其他类型的字符(当然除了 null )。但是,空字符串本身也算作参数,所以:

echo HELLO "" WORLD!

应该输出:

HELLO  WORLD!

中间有2个空格,不是:

HELLO WORLD!

只有一个(因为空字符串是一个参数)。

我希望这不会太令人困惑。如果你们需要任何澄清,请询问;我很乐意发布代码。

【问题讨论】:

    标签: c shell unix exec echo


    【解决方案1】:

    它是在解析命令行时去掉引号的 shell。如果您将它们传递给 exec* 直接调用,则 echo 会回显它们。那么它就相当于echo HELLO '""' WORLD!

    【讨论】:

    • 嗯,所以我需要自己去掉引号,然后再将其传递给 exec*?
    • 如果是空字符串呢?我该如何表示?
    • @Scriptonaut 使用您的示例:[echo0, HELLO0, 0, WORLD!0].
    • 那么我是否必须明确检测我是否正在处理一个空字符串,或者是否有一种通用的方法来处理我的迭代循环中的引号?
    • 好吧,shell 去掉引号的关键是因为它们有意义——将空格分隔的参数合二为一,处理变量扩展,传递空参数等。如果你想要同样的效果——你应该解析根据您的喜好引用。
    【解决方案2】:

    /bin/echo 不知道引号。它只是打印由空格分隔的所有参数。您所说的适用于外壳的原因是外壳知道引号并将空字符串作为第二个参数传递。

    【讨论】:

    • 那么我该如何表示一个空字符串呢?我不能为每个引用插入 null,也不能对每个引用都使用 memmove,因为在某些情况下,我需要一个 args 根本就没有。
    • @Scriptonaut 您需要做好解析引号的工作。这至少需要一个有限状态机。
    【解决方案3】:
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main(void)
    {
        char *args1[] = { "/bin/echo", "HELLO", "\"\"", "WORLD!", 0 };
        char *args2[] = { "/bin/echo", "HELLO", "",     "WORLD!", 0 };
        if (fork() == 0)
        {
            execvp(args1[0], args1);
            exit(1);
        }
        while (wait(0) > 0)
            ;
        execvp(args2[0], args2);
        return(1);
    }
    

    这证明了差异。当您使用 execvp() 时,没有 shell 可以解释 I/O 重定向等 - 尽管在这种情况下,execv() 也可以,因为我已经为 echo 命令指定了路径。

    【讨论】:

    • 那么如何在不插入空字符的情况下省略引号呢?例如,回声 HELLO" "WORLD!是两个参数,echo 和其余的。如果我为每个引号插入一个空字符,它将显示为三个参数。
    • 实际上,这不仅仅是“会做”——指定路径使execvp 的使用毫无意义,如果出于某种原因,echo 只能作为/usr/bin/echo 使用,则事情将失败例子。 (并不是说它与问题有任何关系)。
    • 来吧,@Scriptonaut,这是您的代码,我们如何告诉您应该如何解释您的输入?如果您希望它像使用 shell 运行一样工作,请使用 system
    • @Scriptonaut:args2 数组显示了如何在 C 中表示一个空参数。您尝试过代码吗?你观察到它的输出了吗?您是否尝试弄清楚为什么要按原样编写?请注意,空字符串与空指针不同;空指针是不正确的。 (是的,C 中的空字符串由相邻的双引号表示是令人困惑的。)
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 2018-10-08
    • 2015-04-14
    • 1970-01-01
    相关资源
    最近更新 更多