Więc tutaj musimy dwukrotnie przekazać nazwę pliku w funkcji.
Nie są to dokładnie to samo, co zauważysz, obserwując, że jeden z nich jest używany jako argv[0]
wartość. To nie musi być taki sam jak basename pliku wykonywalnego; wiele / większość rzeczy ignoruje to i możesz włożyć tam, co chcesz.
Pierwszy to rzeczywista ścieżka do pliku wykonywalnego, dla którego istnieje oczywista konieczność. Drugi jest przekazywany do procesu pozornie tak, jak nazwa go wywołuje, ale np .:
execl("/bin/ls", "banana", "-l", NULL);
Będzie działać dobrze, zakładając, że /bin/ls
jest to właściwa ścieżka.
Jednak niektóre aplikacje wykorzystują argv[0]
. Zwykle mają one jeden lub więcej dowiązań symbolicznych $PATH
; jest to powszechne w przypadku narzędzi do kompresji (czasami używają zamiast tego owijarek powłok). Jeśli masz xz
zainstalowany, stat $(which xzcat)
pokazuje, że jest to link do xz
i man xzcat
jest taki sam, jak ten, man xz
który wyjaśnia „xzcat jest równoważne z xz --decompress --stdout”. Sposób, w jaki xz może stwierdzić, w jaki sposób został wywołany, polega na sprawdzeniu argv[0]
, czyniąc je równoważnymi:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busybox
może wyglądać to, jak chcesz, w zależności od tego, jak to nazywasz?/bin/ls
był zajęty, nie wiedziałby, jak wykonaćbanana
!Nie musisz podawać nazwy pliku dwa razy.
Pierwszy to plik, który jest faktycznie wykonywany.
Drugi argument dotyczy tego, co powinno być
argv[0]
procesem, tj. Tego , co proces powinien postrzegać jako swoją nazwę. Np. Jeśli uruchamiaszls
z powłoki, pierwszym argumentem jest/bin/ls
, drugi jest po prostuls
.Możesz wykonać określony plik i nazwać go czymś innym za pomocą drugiego argumentu; program może sprawdzić swoją nazwę i zachowywać się inaczej w zależności od nazwy. Można to również zrobić za pomocą twardych łączy (lub dowiązań symbolicznych), ale w ten sposób zapewnia większą elastyczność.
źródło
argv[0]
się nazwę łącza.Na wynos
argv[0]
można ustawić wszystko (w tymNULL
). Umownie ,argv[0]
zostanie ustawiony na ścieżce wykonywalny został uruchomiony jako (w procesie powłoki kiedy to robiexecve()
).Jeśli
./foo
idir/bar
są dwa różne łącza (twarde lub symboliczne) do tego samego pliku wykonywalnego, wówczas uruchomienie programu z powłoki przy użyciu dwóch ścieżek zostanie ustawione odpowiednioargv[0]
na./foo
idir/bar
.Fakt, że
argv[0]
może być,NULL
jest często pomijany. Poniższy kod możeNULL
argv[0]
na przykład ulec awarii (chociaż glibc wypisuje coś takiego jak <null> zamiastargv[0]
):Alternatywą w Linuksie jest zastosowanie
/proc/self/exe
w takich przypadkach.źródło
./foo
i raz jakdir/bar
.argv[0]
będzie różny dla tych dwóch przypadków (w każdym przypadku będzie taki sam, jak użyta ścieżka).argv[0]
wszystko, kiedy samexec*()
program. Jest to konwencja powłoki ustawianaargv[0]
na ścieżkę użytą do uruchomienia programu (i rozsądnie jest zrobić to samo, gdyexec*()
program, ponieważ wiele programów sprawdzaargv[0]
i oczekuje, że utrzyma ścieżkę).