9

組み込みコマンドを使用して基本的なシェルを作成しようとしていますが、getopt で問題が発生しています。出力は次のとおりです (valgrind を使用)。

$ mkdir -p foo/bar
mkdir
-p
foo/bar
FLAGON
$ mkdir -p foo/test
mkdir
-p
foo/test
==15377== Invalid read of size 1
==15377==    at 0x5201BBE: _getopt_internal_r (in /usr/lib/libc-2.17.so)
==15377==    by 0x5202CEA: _getopt_internal (in /usr/lib/libc-2.17.so)
==15377==    by 0x5202D37: getopt (in /usr/lib/libc-2.17.so)
==15377==    by 0x40351A: shell_ns_cmd_mkdir (shell.c:542)
==15377==    by 0x403AB4: normal_shell_cb (shell.c:610)
==15377==    by 0x402E8E: shell_mainloop (shell.c:402)
==15377==    by 0x401B67: main (main.c:52)
==15377==  Address 0x54e0912 is 2 bytes inside a block of size 3 free'd
==15377==    at 0x4C2AD3C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15377==    by 0x402C93: shell_mainloop (shell.c:384)
==15377==    by 0x401B67: main (main.c:52)
==15377== 
$ 

そして、ここにソースがあります(切り取られています):

for (i = 0; i < argc; i++) {
    puts(argv[i]);
}
while ((c = getopt(argc, argv, "p")) != -1) {
    switch (c) {
        case 'p':
            puts("FLAGON");
            mkparents = true;
            break;
        case '?':
            fprintf(stderr, "invalid option -- %c", optopt);
            ret = 127;
            goto end;
            break;
    }
}

したがって、最初に実行すると ( mkdir -p) 認識され ( -p)、2 回目に実行すると認識されません。何か案は?

4

1 に答える 1

19

getopt複数のベクトルをスキャンする場合は、1に設定してリセットする必要がありますoptind

変数 optind は、処理される argv[] ベクトルの次の要素のインデックスです。システムによって 1 に初期化され、 argv[] の各要素で終了すると getopt() によって更新されます。

1 に設定optindしてもうまくいかない場合は、 も試してみてください0。それについてどこかで読んだことを覚えていると思います。

于 2013-03-02T22:08:24.973 に答える