この 2 日間、execlp()
を理解しようとしました。 システムコールですが、それでもここにいます。さっそく本題に入らせてください。
man page
の execlp は、システム コールを int execlp(const char *file, const char *arg, ...);
として宣言します。 説明:execl()、execlp()、および execle() 関数の const char arg とそれに続く省略記号は、arg0、arg1、...、argn と考えることができます。
それでも、私たちのテキストブックでは、システムコールが次のように呼び出されているのを見ます:execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);
(「...」は学生として理解するためのものです)。ただし、このシステム コールは、man page
の宣言とはまったく似ていません。 システムコールの.
私はとても混乱しています。どんな助けでも大歓迎です。
答え:
このプロトタイプ:
int execlp(const char *file, const char *arg, ...);
execlp は可変引数関数であると言います。 2 const char *
かかります .残りの引数は、もしあれば、実行したいプログラムに渡す追加の引数です - これも char *
- これらはすべて C 文字列です (最後の引数は NULL ポインターでなければなりません)
つまり、file
引数は、実行する実行ファイルのパス名です。 arg
argv[0]
として表示したい文字列です 実行可能ファイルで。慣例により、argv[0]
実行可能ファイルのファイル名です。通常は file
と同じに設定されます .
...
実行可能ファイルに与える追加の引数になりました。
これをコマンドライン/シェルから実行するとします:
$ ls
それは execlp("ls", "ls", (char *)NULL);
です
または実行した場合
$ ls -l /
それは execlp("ls", "ls", "-l", "/", (char *)NULL);
です
execlp("/bin/sh", ..., "ls -l /bin/??", ...);
へ
ここでは、シェル /bin/sh に移動し、シェルに実行するコマンドを与えています。そのコマンドは「ls -l /bin/??」です。コマンドライン/シェルから手動で実行できます:
$ ls -l /bin/??
では、シェルを実行してコマンドを実行するように指示するにはどうすればよいでしょうか。シェルのドキュメント/man ページを開き、それを読みます。
実行したいものは次のとおりです:
$ /bin/sh -c "ls -l /bin/??"
これは
execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);
補足:
/bin/??
はパターン マッチングを行っていますが、このパターン マッチングはシェルによって行われ、/bin/ 以下の 2 文字のすべてのファイルに展開されます。単純に
execlp("ls","ls", "-l", "/bin/??", (char *)NULL);
おそらく何も起こらないでしょう (実際に /bin/??
という名前のファイルがない限り) ) /bin/?? を解釈して展開するシェルがないため