ではexecl()
、引数を 1 つずつリストする必要があります。事前に何を実行するかを正確に知っている場合にのみ役立ちます。
execl("/bin/ls", "ls", "-l", (char *)0);
execl("/bin/sh", "sh", "-c", "ls -l", (char *)0);
execl("/bin/ls", "pink elephants", "-l", (char *)0);
等。
対処しなければならない引数の数がわからない場合は、またはファミリexecvp()
の他のメンバーの 1 つを使用してください。execv*()
また、コマンドのパスを指定する必要があることに注意してください。execvp()
は検索を実行します$PATH
が、execl()
実行しません。として渡された値を選択できることにも注意してくださいargv[0]
。
このアプローチを採用した理由execl()
は、バイナリのパスが異なる可能性があるexecvp()
のに、その機能を提供しなかったためです。
ここで何を意味するのかわかりません。ではexecvp()
、次を指定できます。
char *argv[] = { "ls", "-l", 0 };
execvp(argv[0], argv);
execv("/bin/ls", argv);
はonexecvp()
を検索し、一致する最初のプログラムを実行します。2 番目は、まったく見ずに実行されます。ls
$PATH
/bin/ls
$PATH
char *argv[] = { "/bin/ls", "-l", 0 };
execv(argv[0], argv);
execvp(argv[0], argv);
これらのいずれかが機能します。argv[0]
2 つ目は、実行可能ファイル名 ( ) にスラッシュが含まれているため、PATH ベースの検索を使用しません。
私を混乱させているのは、execvp(argv[0], argv);
なぜ全体argv
を2番目のパラメーターとして渡すのですか? argv[0]
だったとします。なぜ"ls -l"
全体argv
を 2 番目のパラメータとして渡す必要があるのでしょうか。
argv[0]
が含まれていると仮定"ls -l"
すると、問題があります。ほとんどのシステムにはファイル " /bin/ls -l
" または " /usr/bin/ls -l
" (空白は名前の一部) がありませんが、実行したいのはそれです。
関数は、プロセスを実行するためのexec*()
低レベル関数です。最初の引数は、実行するプログラムを指定します (通常はバイナリ。最初の行などのシバン行を含むスクリプトの場合もあります#!/bin/sh
)。execv()
またはexecvp()
またはexecve()
またはの場合、関数が引数のベクトル (または引数ベクトル、したがって ) を受け取るのexecvpe()
と同様に、2 番目の引数は引数のベクトルです。これは、プログラムへの引数のヌル終了リストです。オプションを指定してコマンドを実行する場合は、3 つの値 (!)と null ポインターを指定する必要があります。main()
argv
ls
-l
argv
"ls"
"-l"
char argv[] = { "ls", "-l", 0 };
関数を使用してexecl*()
、実行するプログラムを最初の引数として指定し、その後に引数ベクトルを書き出します。
execl("/bin/ls", "ls", "-l", (char *)0);
引数が 10 個ある場合は、10 個の引数 (およびヌル ポインター) を書き出す必要があります。
exec*()
関数では、名前に次のものが含まれます。
l
— リスト形式の引数
v
— ベクトル形式の引数
p
— プログラムで PATH ルックアップを実行します (指定された名前にスラッシュが含まれていない場合)
e
— 環境変数のベクトルも取ります
これらを組み合わせると、次のようになります。
execl()
execv()
execlp()
execle()
execvp()
execve()
execlpe()
andがないのは少し面倒な場合がありexecvpe()
ます (ただし、Linux 拡張機能を参照してくださいexecvpe(3)
)。また、ページの概要からこれらの一部を省略し、マニュアル ページの本文で言及することも伝統的です。これはman 2 exec
、少なくとも 1979 年の第 7 版 UNIX™ にさかのぼる伝統/遺産です (少なくとも RHEL 5 Linux まで永続化されました)。および Mac OS X 10.7.5 (このman 2 execl
ページでは言及されていますexecve()
が、「概要」セクションには記載されていません)。他のexec*()
関数はすべて上に構築できますexecve()
— これがセットの基本的な関数です (execve(2)
結果として、Linux マニュアルのようにリストされています)。