C UNIX Shell execvp回显引号
因此,我正在用C编写一个基本的UNIX minishell。一切都进行得很顺利,但最近我重新定义了它从控制台获取的原始字符串解析参数的方式。下面是一个解析方式的示例: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在我的例子中不是内置命令,所以我无
$> 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表示是令人困惑的