0

だから私はCで基本的なUNIXミニシェルをプログラミングしています。すべてが順調に進んでいますが、最近、コンソールから取得した元の文字列から引数を解析する方法をやり直しました。解析方法の例を次に示します。

$> 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!

1つだけで(空の文字列は引数であるため)。

これがあまり混乱しないことを願っています。何か説明が必要な場合は、質問してください。コードを投稿させていただきます。

4

3 に答える 3

2

コマンドラインを解析するときに引用符を取り除くのはシェルです。それらを渡してexec*直接呼び出すと、echoはそれらをエコーし​​ます。その場合、はと同等echo HELLO '""' WORLD!です。

于 2012-10-14T20:27:52.453 に答える
1

/bin/echo引用符について知りません。スペースで区切られたすべての引数を出力するだけです。あなたが言ったことがシェルで機能する理由は、シェルが引用符を知っていて、2番目の引数として空の文字列を渡すためです。

于 2012-10-14T20:30:56.160 に答える
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);
}

これは違いを示しています。使用時にI/Oリダイレクトなどを解釈するシェルはありません。execvp()ただし、この場合はexecv()、コマンドのパスを指定したので、同様に解釈できますecho

于 2012-10-14T20:52:49.790 に答える