181 votes

Comment obtenir le chemin d'un processus sous Unix / Linux

Dans l'environnement Windows, il existe une API pour obtenir le chemin qui exécute un processus. Y a-t-il quelque chose de similaire sous Unix / Linux?

Ou existe-t-il un autre moyen de le faire dans ces environnements?

236voto

jpalecek Points 31928

Si vous voulez le chemin de l'exécutable actuel, regardez /proc/$PID/exe , qui est un lien symbolique vers celui-ci.

100voto

hahakubile Points 221

Vous pouvez trouver le fichier exe facilement par ces moyens, essayez-le vous-même.

  • ll /proc/<PID>/exe
  • pwdx <PID>
  • lsof -p <PID> | grep cwd

31voto

Hiperion Points 221

Un peu tard, mais toutes les réponses étaient spécifiques à Linux.

Si vous avez aussi besoin d'unix, alors vous avez besoin de ceci:

 char * getExecPath (char * path,size_t dest_len, char * argv0)
{
    char * baseName = NULL;
    char * systemPath = NULL;
    char * candidateDir = NULL;

    /* the easiest case: we are in linux */
    if (readlink ("/proc/self/exe", path, dest_len) != -1)
    {
        dirname (path);
        strcat  (path, "/");
        return path;
    }

    /* Ups... not in linux, no  guarantee */

    /* check if we have something like execve("foobar", NULL, NULL) */
    if (argv0 == NULL)
    {
        /* we surrender and give current path instead */
        if (getcwd (path, dest_len) == NULL) return NULL;
        strcat  (path, "/");
        return path;
    }


    /* argv[0] */
    /* if dest_len < PATH_MAX may cause buffer overflow */
    if ((realpath (argv0, path)) && (!access (path, F_OK)))
    {
        dirname (path);
        strcat  (path, "/");
        return path;
    }

    /* Current path */
    baseName = basename (argv0);
    if (getcwd (path, dest_len - strlen (baseName) - 1) == NULL)
        return NULL;

    strcat (path, "/");
    strcat (path, baseName);
    if (access (path, F_OK) == 0)
    {
        dirname (path);
        strcat  (path, "/");
        return path;
    }

    /* Try the PATH. */
    systemPath = getenv ("PATH");
    if (systemPath != NULL)
    {
        dest_len--;
        systemPath = strdup (systemPath);
        for (candidateDir = strtok (systemPath, ":"); candidateDir != NULL; candidateDir = strtok (NULL, ":"))
        {
            strncpy (path, candidateDir, dest_len);
            strncat (path, "/", dest_len);
            strncat (path, baseName, dest_len);

            if (access(path, F_OK) == 0)
            {
                free (systemPath);
                dirname (path);
                strcat  (path, "/");
                return path;
            }
        }
        free(systemPath);
        dest_len++;
    }

    /* again someone has use execve: we dont knowe the executable name; we surrender and give instead current path */
    if (getcwd (path, dest_len - 1) == NULL) return NULL;
    strcat  (path, "/");
    return path;
}
 

4voto

hyperboreean Points 3043

Sous Linux, chaque processus a son propre dossier dans /proc . Vous pouvez donc utiliser getpid() pour obtenir le pid du processus en cours, puis le joindre avec le chemin /proc pour obtenir le dossier dont vous avez besoin, espérons-le.

Voici un court exemple en Python:

 import os
print os.path.join('/proc', str(os.getpid()))
 

Voici l'exemple en ANSI C:

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>


int
main(int argc, char **argv)
{
    pid_t pid = getpid();

    fprintf(stdout, "Path to current process: '/proc/%d/'\n", (int)pid);

    return EXIT_SUCCESS;
}
 

Compilez-le avec:

 gcc -Wall -Werror -g -ansi -pedantic process_path.c -oprocess_path 
 

3voto

Vatine Points 8884

Il n'y a pas de "garantie de travailler n'importe où" la méthode.

L'étape 1 consiste à vérifier argv[0], si le programme a commencé par son chemin d'accès complet, ce sera (normalement) avoir le chemin d'accès complet. Si il a été lancé par un chemin d'accès relatif, la situation est la même (même si cela nécessite d'avoir le répertoire de travail courant, à l'aide de getcwd().

L'étape 2, si aucune de ce qui précède vaut, est d'obtenir le nom du programme, puis obtenir le nom du programme de argv[0], puis obtenir le CHEMIN d'accès utilisateur à partir de l'environnement et de passer par là pour voir si il y a un adapté binaire exécutable avec le même nom.

Notez que argv[0] est défini par le processus de execs le programme, de sorte qu'il n'est pas fiable à 100%.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X