2

以下のコードをexeclバリアントで使用すると、機能しますが、ls機能ls -lしませんが、私のexecvpアプローチlsls-lは機能します。execl私がこのアプローチを採用した理由は、バイナリのパスが異なる可能性があるのに対し、execvpその機能を提供しなかったためです。execl理想的には、にも取り組みたいls -lのですが、今はうまくいきませんls -l。マニュアルページを読んでみましたが、役に立ちませんでした。

void child(int argc, char *argv[MAX_ARGS])
{
        execvp(argv[0], argv);
}


void child(char *argv[], char* path)
{
        execl(path, argv, NULL);
}
4

1 に答える 1

14

では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()argvls-largv"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 マニュアルのようにリストされています)。

于 2013-02-22T04:56:09.827 に答える