回答:
したがって、ここでは関数でファイル名を2回渡す必要があります。
それらの1つがargv[0]
値として使用されていることを確認すると、これらはまったく同じではありません。これは、実行可能ファイルのベース名と同じである必要はありません。多くの/ほとんどのものがそれを無視し、あなたはそこに好きなものを置くことができます。
1つ目は、実行可能ファイルへの実際のパスです。これには明らかに必要があります。2番目のものは、それを呼び出すために使用された名前としてプロセスに渡されますが、例えば:
execl("/bin/ls", "banana", "-l", NULL);
正常に動作し/bin/ls
、正しいパスであると推定されます。
ただし、一部のアプリケーションはを使用しargv[0]
ます。通常、これらにはに1つ以上のシンボリックリンクがあり$PATH
ます。これは圧縮ユーティリティでは一般的です(代わりにシェルラッパーを使用する場合があります)。xz
インストールした場合、それはstat $(which xzcat)
へのリンクであることを示しxz
、「xzcatはxz --decompress --stdoutと同等」を説明man xzcat
するものと同じman xz
です。xzがどのように呼び出されたかを知る方法は、をチェックしてargv[0]
、これらを同等にすることです。
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
/bin/ls
つまり、busyboxの場合、実行方法がわかりませんbanana
。
ファイル名を2回渡す必要はありません。
1つ目は、実際に実行されるファイルです。
2番目の引数はargv[0]
、プロセスの名前、つまりプロセスがその名前として何を表示するかです。たとえばls
、シェルから実行する場合、最初の引数は/bin/ls
、2番目の引数はls
です。
特定のファイルを実行して、2番目の引数を介して別のファイルを呼び出すことができます。プログラムはその名前をチェックし、名前に応じて異なる動作をすることができます。これはハードリンク(またはシンボリックリンク)を介して行うこともできますが、これにより柔軟性が高まります。
argv[0]
リンク名に設定されるため、リンクは同じメソッドです。
要点は、argv[0]
何でも設定できることです(を含むNULL
)。慣例では、argv[0]
(それがないシェルプロセスで実行可能として開始されたパスに設定されますexecve()
)。
場合./foo
とdir/bar
同じ実行する(ハードまたはシンボリック)は、2つの異なるリンクであり、次いで、セットする二つの経路を使用してシェルからプログラムを起動argv[0]
する./foo
とdir/bar
、それぞれ、。
ありargv[0]
得る事実NULL
はしばしば見落とされます。NULL
argv[0]
たとえば、次のコードはクラッシュする可能性があります(glibcはの代わりに<null>のようなものを出力しますargv[0]
)。
if (argc != 3) {
fprintf(stderr, "%s: expected 2 arguments\n", argv[0]);
exit(EXIT_FAILURE);
}
Linuxの代替手段は/proc/self/exe
、このような場合に使用することです。
./foo
と1回dir/bar
。argv[0]
これらの2つのケースでは異なります(どちらの場合も、使用したパスと同じになります)。
argv[0]
を作成するときにexec*()
、何にでも設定できるということです。argv[0]
プログラムを起動するために使用されたパスに設定するのはシェルの規則です(exec*()
多くのプログラムargv[0]
がパスを保持していることを検査して期待するため、プログラムを実行するときに同じことを行うのが賢明です)。
busybox
あなたがそれをどのように正しく呼ぶかに依存して、あなたがそれがどのようになりたいかを説明することができるでしょうか?