2012-10-14 13 views
0

所以我用C编写了一个基本的UNIX minishell。一切都很顺利,但是我最近重新分析了它从它从控制台获得的原始字符串中分析参数的方式。下面是它的解析方式的一例:C UNIX Shell execvp回声引号

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

参数数组看起来像这样:[!echo0,HELLO0 “” 0,WORLD 0]

我通过它像这样:

execvp(args[0], args); 

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

echo HELLO "" WORLD! 

应该输出:

HELLO WORLD! 

与2位之间,而不是:

HELLO WORLD! 

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

我希望这不是太混乱。如果你们需要澄清,请问一下;我很乐意发布代码。

回答

2

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

+0

嗯,所以我需要自己剥夺报价之前,将它传递给exec *? – robins35

+0

在空串的情况下怎么样?我如何表达? – robins35

+0

@Scriptonaut使用你的例子:'[echo0,HELLO0,0,WORLD!0]'。 –

1

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

+0

那么我该如何表示一个空字符串?我无法为每个引用插入null,并且我不能为每个引用使用memmove,因为有一些情况下我需要我的一个参数。 – robins35

+0

@Scriptonaut你需要做一个解析报价的适当工作。这至少需要一个有限状态机。 – dmckee

1
#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()时,没有解释I/O重定向等的方法 - 尽管在这种情况下,execv()也可以执行,因为我已经指定了echo命令的路径。

+0

那么,如何在不插入空字符的情况下省略引号? 例如, echo HELLO“”WORLD! 是两个参数,echo和其余。如果我为每个引号插入一个空字符,它将显示为三个参数。 – robins35

+0

实际上,它不仅仅是“会做” - 指定路径使得'execvp'的使用毫无意义,如果出于某种原因,例如'echo'仅作为'/ usr/bin/echo'可用,则该事件将失败。 (并不是说它与这个问题有任何关系)。 –

+0

来吧,@Scriptonaut,它是你的代码,我们如何告诉你你的输入应该如何解释?如果你想让它像使用shell一样运行,就使用'system'。 –