8

execvp()Cで言うと、任意の文字列コマンドを呼び出したいと思います。コマンドは次のようになります。

char command[] = "ls -l";
char command[] = "rm *.txt";
char command[] = "cat makefile";

このコマンド変数をの中に入れたいですexecvp()。したがって、exec()フレーバー関数は、任意の種類の任意のコマンドで実行できます。

どうやってやるの?ありがとう。

注:system()許可されていません。

4

5 に答える 5

11

を呼び出す必要ある場合execvp()は、これらの文字列を実行可能ファイル名と引数の配列に分割する必要があります(最初はプログラムの「名前」で、最後はNULLポインターです)。

つまり、次のような意味です。

char cmd1[] = "ls";  char *args1[] = {"ls", "-l", NULL};
char cmd1[] = "rm";  char *args1[] = {"rm", "*.txt", NULL}; // but see
                                                            // globbing below.
char cmd1[] = "cat"; char *args1[] = {"cat", "makefile", NULL};

これは、特に引用、グロブ、エスケープなどを許可したい場合は、重要な演習です。

引用するということは、次のようなコマンドに注意する必要があることを意味します。

rm "file with spaces.txt"

スペースを単純に分割することはできません。コマンド内の項目は、シェルとほぼ同じように解釈する必要があります。スペースを単純に分割すると、正しい文字列ではなく、上記の文字列に対して3つの引数を持つコマンドが得られます。

*.txtグロブとは、通常、これらの引数を拡張するシェルであるため、ほぼ確実に次のような問題が発生することを意味します。これを直接に渡すと、現在のディレクトリ内のすべてのテキストファイルに一致する多くの引数ではなく、文字通りexecvp()単一の引数になります。*.txt

引用とは、次のような処理を行う必要があることを意味します。

ls -l "file with spaces and \" quote in it"

これにより、パーサーがさらに複雑になります。

誤解しないでください、それは可能ですが、それを使用するだけでおそらく気の利いた光景ですsystem()

あなたがまだexecvp()ルートに行くことを考えているなら、あなたはしなければならないでしょう:

  • 文字列を別々のトークンに分割します(引用符とエスケープを処理する必要があるため、かなり難しいです)。
  • すべての引数をグロブします。つまり、ワイルドカードが含まれている引数(および引用符で囲まれているためにエスケープまたは保護されていない引数のみ)は、複数の引数に展開されます。
  • コマンドを先頭に、NULLを末尾に指定して、引数配列を作成します。
  • execvp()その配列の最初の要素であるパラメータと配列のアドレスを使用して呼び出します。
于 2011-11-11T03:37:52.947 に答える
5

いいえ、exec関数ファミリーは、のように単一の文字列コマンドラインを使用systemしません。代わりにargv、文字列のような配列を使用します。

char *command = "/path/to/command";
char *arguments[] = { "command", "first argument", "second argument", NULL };
execvp(command, arguments);

配列の最初のエントリargumentsはコマンド自体であり、配列はで終了することに注意してくださいNULL

マニュアルページを確認しましたか?

于 2011-11-11T03:37:54.703 に答える
3

execveスタイルの関数を使用するには、コマンドラインを自分で解析してargvベクトルを作成する必要があります。関数はchar**を取ります。ここで、最後の要素はnullです。これらすべてに十分なメモリを割り当てる必要があります。そうすれば、execveスタイルの呼び出しが機能するはずです。

(psフォークについては何も言及していません...)

于 2011-11-11T03:38:00.123 に答える
1

「*」>「」、「<」、「&」などを機能させるには、「/ bin / sh」を実行し、コマンドラインを引数として渡す必要があります。つまり、文字列をトークン化することになります。

于 2011-11-11T03:39:13.053 に答える
1

ここで行う必要があるのは、シェルにコマンドを解析させることです。したがって、これを考慮してください:

/bin/sh -c 'rm *.txt'

それはあなたを正しい方向に向かわせるはずです。:)

于 2011-11-11T05:46:50.607 に答える