Als een argument wordt doorgegeven aan main()
in een C- of C++-toepassing, zal argv[0]
dan altijd de naam zijn van het uitvoerbare bestand? Of is dit gewoon een algemene conventie en is het niet gegarandeerd dat het 100% van de tijd waar is?
Antwoord 1, autoriteit 100%
Gissen (zelfs goed giswerk) is leuk, maar je moet echt naar de standaarddocumenten gaan om zeker te zijn. ISO C11 stelt bijvoorbeeld (mijn nadruk):
Als de waarde van
argc
groter is dan nul, staat de tekenreeks waarnaar wordt verwezen doorargv[0]
voorde programmanaam;argv[0][0]
is het null-teken als de programmanaam niet beschikbaar is in de hostomgeving.
Dus nee, het is alleen de programmanaam als die naam beschikbaar is.En het ‘vertegenwoordigt’de programmanaam, niet per se isde programmanaam. In het gedeelte daarvoor staat:
Als de waarde van
argc
groter is dan nul, zullen de arrayledenargv[0]
tot en metargv[argc-1]
inclusief bevatten verwijzingen naar tekenreeksen, die door de hostomgeving vóór het opstarten van het programma door de implementatie gedefinieerde waarden krijgen.
Dit is ongewijzigd ten opzichte van C99, de vorige standaard, en betekent dat zelfs de waardenniet door de standaard worden gedicteerd – het is volledig aan de implementatie.
Dit betekent dat de programmanaam leeg kan zijn als de hostomgeving deze nietlevert, en al het andere als de hostomgeving deze welverschaft, op voorwaarde dat ” iets anders” vertegenwoordigt op de een of andere manier de programmanaam. Op mijn meer sadistische momenten zou ik overwegen om het in het Swahili te vertalen, het door een substitutiecijfer te laten lopen en het vervolgens in omgekeerde bytevolgorde op te slaan :-).
Implementatiegedefinieerde heeft echtereen specifieke betekenis in de ISO-normen – de implementatie moet documenteren hoe het werkt. Dus zelfs UNIX, dat alles wat het wil in argv[0]
kan stoppen met de exec
-familie van aanroepen, moet (en doet) het documenteren.
Antwoord 2, autoriteit 41%
Onder systemen van het type *nix
met exec*()
-aanroepen, zal argv[0]
zijn wat de beller in de argv0
-plek in de exec*()
-aanroep.
De shell gebruikt de conventie dat dit de programmanaam is, en de meeste andere programma’s volgen dezelfde conventie, dus argv[0]
meestal de programmanaam.
Maar een malafide Unix-programma kan exec()
aanroepen en argv[0]
alles maken wat het wil, dus wat de C-standaard ook zegt, je kunt het niet reken hier 100% van de tijd op.
Antwoord 3, autoriteit 7%
Volgens de C++-standaard, sectie 3.6.1:
argv[0] is de aanwijzer naar de
beginteken van een NTMBS die
staat voor de naam die wordt gebruikt om de . aan te roepen
programma of “”
Dus nee, het wordt niet gegarandeerd, althans niet door de Standaard.
Antwoord 4, autoriteit 5%
ISO-IEC 9899 stelt:
5.1.2.2.1 Opstarten van programma
Als de waarde van
argc
groter is dan nul, wordt de tekenreeks waarnaar wordt verwezen doorargv[0]
vertegenwoordigt de programmanaam;argv[0][0]
is het null-teken als de programmanaam niet beschikbaar is in de hostomgeving. Als de waarde vanargc
groter is dan één, worden de tekenreeksen waarnaar wordt verwezen doorargv[1]
tot en metargv[argc-1]
vertegenwoordigen de programmaparameters.
Ik heb ook gebruikt:
#if defined(_WIN32)
static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
{
return GetModuleFileNameA(NULL, pathName, (DWORD)pathNameCapacity);
}
#elif defined(__linux__) /* elif of: #if defined(_WIN32) */
#include <unistd.h>
static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
{
size_t pathNameSize = readlink("/proc/self/exe", pathName, pathNameCapacity - 1);
pathName[pathNameSize] = '\0';
return pathNameSize;
}
#elif defined(__APPLE__) /* elif of: #elif defined(__linux__) */
#include <mach-o/dyld.h>
static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
{
uint32_t pathNameSize = 0;
_NSGetExecutablePath(NULL, &pathNameSize);
if (pathNameSize > pathNameCapacity)
pathNameSize = pathNameCapacity;
if (!_NSGetExecutablePath(pathName, &pathNameSize))
{
char real[PATH_MAX];
if (realpath(pathName, real) != NULL)
{
pathNameSize = strlen(real);
strncpy(pathName, real, pathNameSize);
}
return pathNameSize;
}
return 0;
}
#else /* else of: #elif defined(__APPLE__) */
#error provide your own implementation
#endif /* end of: #if defined(_WIN32) */
En dan hoeft u gewoon de tekenreeks te ontleden om de uitvoerbare naam uit het pad te halen.
Antwoord 5, Autoriteit 4%
toepassingen van het hebben van argv[0] !=
uitvoerbare naam
-
Veel schelpen bepalen of ze een login-shell zijn door
argv[0][0] == '-'
te controleren. Aanmeldingsschelpen hebben verschillende eigenschappen, met name dat ze een aantal standaardbestanden vinden, zoals/etc/profile
.Het is meestal de init zelf of
getty
die de toonaangevende-
, zie ook: HTTPS://unix.stackExchange.com/Questions/299408/HOW- To-login-automatisch-zonder-typ-the-root-gebruikersnaam-of-wachtwoord-in-build / 300152 # 300152 -
Multi-call binaries, misschien wel met name busybox . Deze symlink meerdere namen b.v.
/bin/sh
EN/bin/ls
NAAR EEN ENKELE EXEBLUTE/bin/busybox
, die erkent welk gereedschap u wilt gebruiken vanargv[0]
.Dit maakt het mogelijk om een enkel klein statiek gekoppeld uitvoerbaar bestand te hebben dat meerdere hulpmiddelen vertegenwoordigt en in principe werkt op een Linux-omgeving.
Zie ook: HTTPS: //unix.stackexchange. COM / VRAGEN / 315812 / Why-DOS-ARGV-omvat-de-programmeernaam / 315817
Runnable Posix execve
Voorbeeld waar argv[0] !=
uitvoerbare naam
Andere noemde exec
, maar hier is een voorbeeld van het fruit.
a.c
#define _XOPEN_SOURCE 700
#include <unistd.h>
int main(void) {
char *argv[] = {"yada yada", NULL};
char *envp[] = {NULL};
execve("b.out", argv, envp);
}
b.c
#include <stdio.h>
int main(int argc, char **argv) {
puts(argv[0]);
}
Dan:
gcc a.c -o a.out
gcc b.c -o b.out
./a.out
Geeft:
yada yada
Ja, argv[0]
kan ook zijn:
Getest op Ubuntu 16.10.
Antwoord 6, autoriteit 2%
Op deze paginastaat:
Het element argv[0] bevat normaal gesproken de naam van het programma, maar hier mag niet op worden vertrouwd – het is hoe dan ook ongebruikelijk dat een programma zijn eigen naam niet kent!
Andere pagina’s lijken echter te bevestigen dat het altijd de naam is van het uitvoerbare bestand. Dezestelt:
Je zult merken dat argv[0] het pad en de naam van het programma zelf is. Hierdoor kan het programma informatie over zichzelf ontdekken. Het voegt ook nog een toe aan de reeks programmaargumenten, dus een veelvoorkomende fout bij het ophalen van opdrachtregelargumenten is om argv[0] te pakken als je argv[1] wilt.
Antwoord 7, autoriteit 2%
Ik weet niet zeker of het een bijna universele conventie of een standaard is, maar je moet je er hoe dan ook aan houden. Ik heb het echter nooit buiten Unix en Unix-achtige systemen zien misbruiken. In Unix-omgevingen – en misschien vooral vroeger – kunnen programma’s significant verschillend gedrag vertonen, afhankelijk van de naam waaronder ze worden aangeroepen.
BEWERKT: ik zie uit andere berichten op hetzelfde moment als de mijne dat iemand heeft vastgesteld dat het van een bepaalde standaard komt, maar ik weet zeker dat de conventie al lang ouder is dan de standaard.
Antwoord 8
Als je een Amiga-programma start via Workbench, wordt argv[0] niet ingesteld, alleen door CLI.