Hier müssen wir also den Dateinamen in der Funktion zweimal übergeben.
Sie sind nicht ganz dasselbe, wie Sie feststellen, wenn Sie beobachten, dass einer von ihnen als argv[0]
Wert verwendet wird. Dies muss nicht mit dem Basisnamen der ausführbaren Datei identisch sein. Viele / die meisten Dinge ignorieren es und Sie können alles hineinstecken, was Sie wollen.
Der erste ist der tatsächliche Pfad zur ausführbaren Datei, für die eine offensichtliche Notwendigkeit besteht. Der zweite wird angeblich als der Name, der zum Aufrufen verwendet wird, an den Prozess übergeben, aber z.
execl("/bin/ls", "banana", "-l", NULL);
Funktioniert gut, vorausgesetzt, es /bin/ls
ist der richtige Weg.
Einige Anwendungen verwenden jedoch argv[0]
. Normalerweise haben diese einen oder mehrere Symlinks $PATH
; Dies ist bei Komprimierungsprogrammen üblich (manchmal verwenden sie stattdessen Shell-Wrapper). Wenn Sie xz
installiert ist , stat $(which xzcat)
zeigt es ist ein Link zu xz
, und man xzcat
ist die gleiche wie man xz
die erklärt , „xzcat äquivalent zu xz --decompress --stdout“. Die Art und Weise, wie xz erkennen kann, wie es aufgerufen wurde, besteht darin, Folgendes zu überprüfen argv[0]
:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busybox
kann, was Sie wollen, je nachdem, wie Sie es richtig nennen?/bin/ls
eine Busybox nicht wissen würde, wie sie ausgeführt werden sollbanana
!Sie müssen den Dateinamen nicht zweimal übergeben.
Die erste ist die Datei, die tatsächlich ausgeführt wird.
Das zweite Argument ist
argv[0]
, was der Prozess sein sollte, dh was der Prozess als seinen Namen sehen sollte. Wenn Sie beispielsweisels
von der Shell aus laufen , ist das erste Argument/bin/ls
das zweitels
.Sie können eine bestimmte Datei ausführen und über das zweite Argument etwas anderes aufrufen. Das Programm kann seinen Namen überprüfen und sich je nach Name unterschiedlich verhalten. Dies kann auch über feste Links (oder symbolische Links) erfolgen, bietet jedoch mehr Flexibilität.
quelle
argv[0]
auf den Linknamen gesetzt wird.Das Mitnehmen ist, dass
argv[0]
auf alles (einschließlichNULL
) eingestellt werden kann. Vereinbarungsgemäß ,argv[0]
wird auf den Pfad gesetzt werden die ausführbare Datei gestartet wurde als (von der Shell - Prozess , wenn es funktioniert dasexecve()
).Wenn
./foo
unddir/bar
zwei verschiedene Verbindungen (hart oder symbolische) zu derselben ausführbar sind, ausgehend dann das Programm von der Schale der beiden Pfade verwendeten , wird eingestelltargv[0]
auf./foo
unddir/bar
ist.Die Tatsache, die sein
argv[0]
kann,NULL
wird oft übersehen. Der folgende Code könnteNULL
argv[0]
beispielsweise für a abstürzen (obwohl glibc stattdessen etwas wie <null> drucktargv[0]
):Eine Alternative unter Linux ist die Verwendung
/proc/self/exe
in solchen Fällen.quelle
./foo
und einmal alsdir/bar
.argv[0]
wird für diese beiden Fälle unterschiedlich sein (in jedem Fall ist es der gleiche wie der Pfad, den Sie verwendet haben).argv[0]
alles einstellen können, wenn Sieexec*()
das Programm selbst. Es ist eine Konvention der Shell,argv[0]
den Pfad festzulegen, der zum Starten des Programms verwendet wurde (und es ist ratsam, dasselbe zu tun, wenn Sieexec*()
ein Programm erstellen, da viele Programmeargv[0]
den Pfad überprüfen und erwarten, dass er den Pfad enthält).