0

Unix ターミナルのような独自のパイプラインを作成したい (練習用)。次のように、アプリケーションを引用符で囲んで実行する必要があります。

パイプライン "ls -l" "grep" ....

stdin と stdout をリダイレクトするには、fork()、execl() (exec*)、および api を使用する必要があることを知っています。しかし、アプリケーションパスと引数を含む引数を1つだけ使用して、execlが引数付きでアプリを実行するための代替手段はありますか? 手動で「ls -l」を解析せずに、1 つの引数として execl に渡す方法はありますか?

4

2 に答える 2

4

引数ベクトルではなく単一のコマンド ラインしかない場合は、シェルに解析を任せます。

execl("/bin/sh", "sh", "-c", the_command_line, NULL);

もちろん、信頼できないリモート ユーザーがこのコマンド ラインに入力できないようにしてください。exec[vl]ただし、最初から信頼できないリモート ユーザー入力を処理している場合は、コマンド ラインではなく、の通常の使用法に従って、分離された引数の実際のリストをターゲット アプリケーションに渡すように手配する必要があります。

于 2013-03-23T12:00:19.423 に答える
3

execl()現実的には、コマンドの引数の数がコンパイル時にわかっている場合にのみ、実際に使用できます。シェルでは、通常、代わりにexecv()orを使用します。execvp()これらは、実行するコマンドに対して任意の数の引数を処理できます。理論的にexecv()は、コマンドのパス名が指定されている場合に使用し、指定execvp()されていない場合に (コマンドの PATH ベースの検索を行います) を使用します。ただし、execvp()「指定されたパス」のケースを処理するため、単純に を使用しますexecvp()

したがって、pipelineコマンドの場合、次のようなものを使用して 1 つの子が作成されます。

char *args_1[] = { "ls", "-l", 0 };
execvp(args_1[0], args_1);

もう一方の子は、次のようなものを使用することになります。

char *args_2[] = { "grep", "pattern", 0 };
execvp(args_2[0], args_2);

もちろん、これらの文字列を、示されているように初期化するのではなく、コマンド ライン引数から作成したことを除きます。grep検索するにはパターンが必要であることに注意してください。

解決すべき配管の問題がまだ残っています。十分なパイプ ファイル記述子を閉じていることを確認してください。dup()標準入力またはdup2()標準出力にパイプするときは、pipe()関数から両方のファイル記述子を閉じます。

于 2013-03-23T11:58:08.223 に答える