21

execvp次のように簡単なコマンドを実行するために使用できることを知っています。

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

を実行すると、ここで何が起こっているのか知りたいですexecvp。manページではexecvp、プロセスイメージのイメージを新しいイメージに置き換えると書かれています。ただし、ここでは実行可能ファイルではなくコマンドを実行しています。

具体的には、cat などの入力が特に必要なコマンドがあるとします。cat に期待されるファイル名を含むテキスト ファイル text.txt があり、stdin をファイルのファイル ストリームにリダイレクトすると、execle("cat","cat",NULL)or execvp("cat", arg)(明らかに arg が格納"cat"されている場所NULL) の出力はコンソールに次のように出力されます。cat /filenameだろうか?私の直感では、ファイルを読み取る必要があり、それを解析して引数を引数に格納する必要があります。ただし、確認したい。

前もって感謝します!

4

4 に答える 4

20

execvp通話中の処理は次のとおりです。

  1. libc 実装はPATH、該当する場合、実行するファイルを で検索します。UNIX ライクなシステムのコマンドは、すべてではないにしてもほとんどが実行可能ファイルです。そうでない場合はどうなりますか?それを試してみてください。glibc がどのようにそれを行うかを見てください。
  2. 通常、実行可能ファイルが見つかった場合は、への呼び出しexecveが行われます。の一部はexecvelibc で実装されるか、またはシステム コール (Linux のように) である可能性があります。
  3. Linux は、プログラムにメモリを割り当て、開き、実行のためにスケジュールし、メモリ構造を初期化し、提供された引数からexecvp呼び出しに引数と環境を設定し、バイナリをロードするのに適切なハンドラーを見つけ、現在のタスクを設定することにより、プログラムを準備します。 (execvp呼び出し元) を実行していません。その実装はここにあります

上記のすべての手順は、関連するマニュアル ページで説明されている POSIX によって設定された要件に準拠しています。

于 2013-01-13T07:56:09.563 に答える
13

ご質問について:

manページではexecvp、プロセスイメージのイメージを新しいイメージに置き換えると書かれています。ただし、ここでは実行可能ファイルではなくコマンドを実行しています。

はるか昔、シェルは非常に限られており、ほとんどすべての UNIX コマンドはスタンドアロンの実行可能ファイルでした。現在、主に速度を向上させるために、UNIX コマンドの一部のサブセットがシェル自体の内部に実装されており、これらのコマンドは と呼ばれbuiltinsます。typeコマンドを介して、シェルに組み込みとして実装されているかどうかを確認できます。

λ ~/ type echo
echo is a shell builtin

man(説明付きのビルトインの完全なリストは、シェルなどのページman bash-builtinsで見つけることができますman builtin。)

ただし、ほとんどのコマンドには、実行可能なカウンターパートがまだあります。

λ ~/ whereis echo
/bin/echo

したがって、実行中の特定のケースでは:

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

実際には、現在のプロセスのアドレス空間を (おそらく) のアドレス空間に置き換えています/bin/ls


私の直感では、ファイルを読み取る必要があり、それを解析して引数を引数に格納する必要があります。

確かにあなたは持っています。ただし、別名「シバン」にいくつかのカーネル内関数を使用することもできます。
ファイル名を別のファイルに入れる代わりに、cat するファイルの最初の行として、いわゆるシバンを追加します。

#!/bin/cat

それに追加chmod +xします。次に、実行可能ファイルとして実行できます (exec関数またはシェルのいずれかを使用)。

λ ~/tmp/ printf '#!/bin/cat\nTEST\n' > cat_me
λ ~/tmp/ chmod +x cat_me
λ ~/tmp/ ./cat_me 
#!/bin/cat
TEST

原因は、ファイルで自分自身を印刷するという欠点がありshebangますが、それでもカーネル内で行うのは楽しいです =)

ところで。xargs標準入力を介して渡された引数のリストで特定のプログラムを実行する(非常に単純化された説明で)呼び出される特別な実行可能ファイルがあるほど一般的である場合に説明した問題。詳細については、に相談してくださいman xargs


-family を簡単にexec覚えるために、次の表をよく使用します。

           Figure 8.14. Differences among the six exec functions
+----------+----------+----------+----------+--------+---------+--------+
| Function | pathname | filename | agr list | argv[] | environ | envp[] |
+----------+----------+----------+----------+--------+---------+--------+
|  execl   |    *     |          |     *    |        |    *    |        |
+----------+----------+----------+----------+--------+---------+--------+
|  execlp  |          |    *     |     *    |        |    *    |        |
+----------+----------+----------+----------+--------+---------+--------+
|  execle  |    *     |          |     *    |        |         |   *    |
+----------+----------+----------+----------+--------+---------+--------+
|  execv   |    *     |          |          |    *   |    *    |        |
+----------+----------+----------+----------+--------+---------+--------+
|  execvp  |          |    *     |          |    *   |    *    |        |
+----------+----------+----------+----------+--------+---------+--------+
|  execve  |    *     |          |          |    *   |         |   *    |
+----------+----------+----------+----------+--------+---------+--------+
|  letter  |          |    p     |     l    |    v   |         |   e    |
+----------+----------+----------+----------+--------+---------+--------+

したがって、あなたの場合execvp、ファイル名、argv( v ) および Environment( e ) を取ります。次に、実行可能なパスが見つかるまで、各パスコンポーネントにfilename(あなたの場合は)を追加することにより、パス名(別名フルパス)を「推測」しようとします。catPATHfilename

execの内部で行われていること (継承関係を含む)に関するより多くの情報は、W. Richard Stevens と Stephen A. Rago aka APUE2 による UNIX 環境での高度なプログラミング (第 2 版) にあります。
UNIX の内部に興味がある場合は、おそらくそれを読む必要があります。

于 2013-01-13T23:10:17.873 に答える
2

「ls」は単なるコマンドではなく、実際にはプログラムです (ほとんどのコマンドはそうです)。そのように execvp を実行すると、プログラム全体、そのメモリ、そのスタック、そのヒープなどを破壊します...概念的には「消去」して「ls」に渡して、それを独自のスタックに使用できるようにします。ヒープなど

つまり、execvp はプログラムを破棄し、別のプログラム (この場合は "ls") に置き換えます。

于 2013-01-13T07:21:52.257 に答える
1

私の直感は、ファイルを読み取る必要があり、それを解析して引数に引数を格納する可能性があるということです。ただし、確認したい。

あなたの直感はおおむね正しいです。例として使用しているcatユーティリティには、2 つの別個のコード パスがあります。

  • 引数としてファイル名が指定されている場合は、ファイルを開いて順番に読み込みます。
  • ファイル名が指定されていない場合は、標準入力から読み取ります。

この動作は、catユーティリティに具体的に実装されており、下位レベルでは実装されていません。特に、それは間違いなくexecシステムコールの一部ではありません. システム コールは、exec引数をまったく「参照」しません。の新しいプロセスにそれらを直接渡すだけでargv、そのプロセスは適切と思われる方法でそれらを処理します。

于 2013-01-13T08:05:07.327 に答える