GNU/Linux >> Linux Esercitazione >  >> Linux

Come trovo la posizione dell'eseguibile in C?

Non una risposta in realtà, ma solo una nota da tenere a mente.

Come abbiamo potuto vedere, il problema di trovare la posizione dell'eseguibile in esecuzione è piuttosto complicato e specifico della piattaforma in Linux e Unix. Bisogna pensarci due volte prima di farlo.

Se hai bisogno della tua posizione eseguibile per scoprire alcuni file di configurazione o di risorse, forse dovresti seguire il modo Unix di posizionare i file nel sistema:put configs to /etc o /usr/local/etc o nella home directory dell'utente corrente, e /usr/share è un buon posto dove mettere i tuoi file di risorse.


Usa la funzione GetModuleFileName() se stai usando Windows.


Tieni presente che i seguenti commenti sono solo unix.

La risposta pedante a questa domanda è che non esiste un generale modo di rispondere correttamente a questa domanda in tutti i casi. Come hai scoperto, argv[0] può essere impostato su qualsiasi cosa dal processo genitore, e quindi non deve avere alcuna relazione con il nome effettivo del programma o con la sua posizione nel file system.

Tuttavia, la seguente euristica spesso funziona:

  1. Se argv[0] è un percorso assoluto, supponi che questo sia il percorso completo dell'eseguibile.
  2. Se argv[0] è un percorso relativo, cioè contiene un / , determina la directory di lavoro corrente con getcwd() e poi aggiungi argv[0] ad essa.
  3. Se argv[0] è una parola semplice, cerca $PATH cercando argv[0] e aggiungi argv[0] a qualsiasi directory in cui lo trovi.

Si noti che tutti questi possono essere aggirati dal processo che ha richiamato il programma in questione. Infine, puoi utilizzare tecniche specifiche di Linux, come menzionato da emg-2. Probabilmente esistono tecniche equivalenti su altri sistemi operativi.

Anche supponendo che i passaggi precedenti ti diano un nome di percorso valido, potresti comunque non avere il nome di percorso che desideri effettivamente (poiché sospetto che ciò che vuoi effettivamente fare sia trovare un file di configurazione da qualche parte). La presenza di hard link significa che puoi avere la seguente situazione:

-- assume /app/bin/foo is the actual program
$ mkdir /some/where/else
$ ln /app/bin/foo /some/where/else/foo     # create a hard link to foo
$ /some/where/else/foo

Ora, l'approccio sopra (incluso, sospetto, /proc/$pid/exe) darà /some/where/else/foo come il vero percorso del programma. E, infatti, è un vero percorso verso il programma, ma non quello che volevi. Nota che questo problema non si verifica con i collegamenti simbolici che sono molto più comuni nella pratica dei collegamenti fisici.

Nonostante il fatto che questo approccio sia in linea di principio inaffidabile, in pratica funziona abbastanza bene per la maggior parte degli scopi.


Per riassumere:

  • Su Unix con /proc modo davvero diretto e affidabile è:

    • readlink("/proc/self/exe", buf, bufsize) (Linux)

    • readlink("/proc/curproc/file", buf, bufsize) (FreeBSD)

    • readlink("/proc/self/path/a.out", buf, bufsize) (Solaris)

  • Su Unix senza /proc (ovvero se quanto sopra fallisce):

    • Se argv[0] inizia con "/" (percorso assoluto) questo è il percorso.

    • Altrimenti se argv[0] contiene "/" (percorso relativo) aggiungilo a cwd (assumendo che non sia stato ancora modificato).

    • Altrimenti cerca le directory in $PATH per l'eseguibile argv[0] .

    Successivamente potrebbe essere ragionevole verificare se l'eseguibile non è effettivamente un collegamento simbolico. Se lo è, risolverlo in relazione alla directory del collegamento simbolico.

    Questo passaggio non è necessario nel metodo /proc (almeno per Linux). Qui il collegamento simbolico proc punta direttamente all'eseguibile.

    Nota che spetta al processo chiamante impostare argv[0] correttamente. È giusto la maggior parte delle volte, tuttavia ci sono occasioni in cui il processo chiamante non può essere considerato attendibile (ad es. setuid eseguibile).

  • Su Windows:usa GetModuleFileName(NULL, buf, bufsize)


Linux
  1. Trova l'URL di un file

  2. come trovare il proprietario di un file o di una directory in python

  3. Come implementare readlink per trovare il percorso

  4. come trovare il percorso HADOOP_HOME su Linux?

  5. Come trovare il file manager predefinito?

Come trovare l'indirizzo IP di una macchina virtuale KVM

Come trovare la dimensione totale di una directory in Linux

Come trovare file con il comando fd in Linux

Come trovare l'elenco dei repository installati in Linux

Come trovare la posizione dei tuoi server con Traceroute e WHOIS

Come trovo la posizione MySQL my.cnf