2

sh -c 使い方やbash -cきちんと調べようとしています。

"sh -c ls"引数なしのような簡単なコマンドを簡単に実行でき ます。

問題は、引数を追加しようとしたときに発生します。するためにls -ltga、私はしなければなりませんでした:

sh -c "ls -ltga"

これは大きな問題ではありませんが、自分で小さなシェルプログラムを作成しようとしている場合を除き、次のことexecveを試してみます。

Argument #:  string
         0:  sh
         1:  -c
         2:  "ls
         3:  -ltga"

そしてそれは私にエラーを与え、次を見つける前にそれがEOFに達したと言っています'"'

私も試しました:

         0:  sh
         1:  -c
         2:  "ls -ltga"

名前の付いたファイル/スクリプトが見つからないと言って私に戻ってきました"ls -ltga"

誰かが私が間違っていることを知っていますか?

4

2 に答える 2

3

の引数の中に引用符を入れないでくださいexecve()。次のように呼び出す必要があります。

char *args = { "sh", "-c", "ls -ltga", 0};
execve("/bin/sh", args);

の最初の引数execve()は、実行可能ファイルへのパス(通常はフルパス)である必要があります。

于 2011-12-04T02:10:36.370 に答える
0

シェルが期待する表記はですsh -c "command plus arguments"。したがって、「回避策」として実行しているのは、実際にはシェルが要求することです。

別の方法は、を使用execvp()して実行することlsです。

char *args[] = { "ls", "-lgta", 0 };
execvp(args[0], args);
fprintf(stderr, "Oops: failed to find 'ls'\n");
exit(1);

また、などの正規表現を使用してコマンドを実行できる必要がありますが、 (ほとんどの場合)それ"rm *.c"は実行に失敗するexecve()ため、代わりにコマンドセット全体を「sh-c」に渡すことでその失敗を回避しようとしています。何か案は?

メタ文字の拡張が必要な​​場合は、シェルを呼び出してそれを実行する必要があります(または、同等のコードを記述して実行する必要があります。これは可能であり、標準のPOSIX関数で実行するのはそれほど難しくありません)。

''を実行するrm *.cには、次を使用します。

char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execv(args[0], args);

または、具体的に合格する必要がある環境がある場合(私はそれがによって示されていると思いますenvp):

char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execve(args[0], args, envp);

exec*関数呼び出し後のエラー処理を忘れないでください。失敗する可能性があります。

于 2011-12-04T02:10:42.747 に答える