C UNIX Shell execvp回显引号

C UNIX Shell execvp回显引号,c,shell,unix,exec,echo,C,Shell,Unix,Exec,Echo,因此,我正在用C编写一个基本的UNIX minishell。一切都进行得很顺利,但最近我重新定义了它从控制台获取的原始字符串解析参数的方式。下面是一个解析方式的示例: $> echo HELLO "" WORLD! HELLO "" WORLD! 参数数组如下所示:[echo0,HELLO0”,“0,WORLD!0] 我这样通过: execvp(args[0], args); 然而,echo应该省略引号,正如您所看到的,它会将它们打印出来。因为echo在我的例子中不是内置命令,所以我无

因此,我正在用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!
只有一个(因为空字符串是参数)


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

在解析命令行时,shell会去掉引号。如果您直接将它们传递给
exec*
call,echo会回显它们。这就相当于
echo HELLO''''WORLD

在解析命令行时,shell将删除引号。如果您直接将它们传递给
exec*
call,echo会回显它们。这就相当于
echo HELLO''''WORLD

/bin/echo
不知道引号。它只打印所有由空格分隔的参数。您所说的与shell一起工作的原因是shell知道引号,并将空字符串作为第二个参数传递。

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

\include
#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);
}
#包括 #包括 内部主(空) { char*args1[]={/bin/echo”,“你好”,“世界!”,0}; char*args2[]={/bin/echo”,“你好”,“世界!”,0}; 如果(fork()==0) { execvp(args1[0],args1); 出口(1); } while(等待(0)>0) ; execvp(args2[0],args2); 申报表(1); }
这说明了两者的区别。当您使用
execvp()
时,没有shell来解释I/O重定向等-尽管在这种情况下,
execv()
也可以,因为我已经为
echo
命令指定了路径。

\include
#包括
#包括
内部主(空)
{
char*args1[]={/bin/echo”,“你好”,“世界!”,0};
char*args2[]={/bin/echo”,“你好”,“世界!”,0};
如果(fork()==0)
{
execvp(args1[0],args1);
出口(1);
}
while(等待(0)>0)
;
execvp(args2[0],args2);
申报表(1);
}


这说明了两者的区别。当您使用
execvp()
时,没有shell来解释I/O重定向等-虽然在这种情况下,
execv()
也可以,因为我已经为
echo
命令指定了路径。

Hmm,所以我需要在将引号传递给exec*之前自己去掉引号。如果是空字符串呢?如何表示?@Scriptonaut使用您的示例:
[echo0,HELLO0,0,WORLD!0]
。那么,我必须显式地检测我是在处理空字符串,还是有一种通用的方法来处理迭代循环中的引号呢,shell strips引号之所以有意义,是因为它们有意义——将空格分隔的参数组合成一个参数,处理变量扩展,传递空参数,等等。如果你想要同样的效果,你应该根据自己的喜好解析引号。嗯,所以我需要在将引号传递给exec*之前自己去掉引号?如果是空字符串呢?如何表示?@Scriptonaut使用您的示例:
[echo0,HELLO0,0,WORLD!0]
。那么,我必须显式地检测我是在处理空字符串,还是有一种通用的方法来处理迭代循环中的引号呢,shell strips引号之所以有意义,是因为它们有意义——将空格分隔的参数组合在一个参数中,处理变量扩展,传递空参数,等等。如果您想要相同的效果,您应该根据自己的喜好解析引号。那么,我如何表示空字符串呢?我不能为每个引号插入null,也不能为每个引号使用memmove,因为在某些情况下,我需要一个参数完全为空。@scripton但您需要正确地解析引号。这至少需要一个有限状态机,那么如何表示空字符串呢?我不能为每个引号插入null,也不能为每个引号使用memmove,因为在某些情况下,我需要一个参数完全为空。@scripton但您需要正确地解析引号。这至少需要一个有限状态机。那么,如何在不插入空字符的情况下省略引号呢?例如,echo HELLO“世界!有两个参数,echo和其他。如果我为每个引号插入一个空字符,它将显示为三个参数。事实上,这不仅仅是“愿意做”——指定路径会使
execvp
的使用变得毫无意义,而且如果出于任何原因,
echo
仅作为
/usr/bin/echo
可用,则该操作将失败。(这与问题没有任何关系。)拜托,@Scriptonaut,这是你的代码,我们如何告诉你你的输入应该如何解释?如果希望它像使用shell一样运行,请使用
system
。@Scriptonaut:
args2
数组显示了如何在C中表示空参数。是否尝试了该代码?你观察到它的输出了吗?你有没有试着弄明白为什么它是这么写的?请注意,空字符串不同于空指针;空指针将不正确。(是的,C中的空字符串用adjace表示是令人困惑的