web-dev-qa-db-ja.com

Linuxでexeclp()がどのように機能するかわかりません

過去2日間、execlp()システムコールを理解しようとしましたが、まだここにいます。問題に直行させてください。

Execlpのman pageは、システムコールをint execlp(const char *file, const char *arg, ...);として宣言します: execle()関数は、arg0、arg1、...、argnと考えることができます。

それでも、テキストブックでシステムコールが次のように呼び出されるのを確認します。execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);(「...」は、学生として把握するためのものです)。ただし、このシステムコールは、システムコールのman pageでの宣言のようなものでさえありません。

私はとても混乱しています。どんな助けも大歓迎です。

30
Arman Iqbal

このプロトタイプ:

_  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/??
_

さて、どのようにシェルを実行してコマンドを実行するように指示しますか?シェルのドキュメンテーション/マニュアルページを開いて読んでください。

実行したいのは:

_$ /bin/sh -c "ls -l /bin/??"
_

これは

_  execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);
_

サイドノート:_/bin/??_はパターンマッチングを行っており、このパターンマッチングはシェルによって行われ、2文字の/ bin /の下のすべてのファイルに展開されます。単純にした場合

_  execlp("ls","ls", "-l", "/bin/??", (char *)NULL);
_

/ bin /?を解釈して展開するシェルがないため、おそらく実際には_/bin/??_という名前のファイルがない限り、何も起こりません。

65
nos

Execlの制限は、現在の作業ディレクトリにないシェルコマンドまたはその他のスクリプトを実行する場合、コマンドまたはスクリプトのフルパスを渡す必要があることです。例:

execl("/bin/ls", "ls", "-la", NULL);

実行可能ファイルのフルパスを渡すための回避策は、ファイルを検索する関数execlpを使用することです(1番目の引数execlpの)PATHが指すディレクトリ内:

execlp("ls", "ls", "-la", NULL);
13
lihudi