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

dans L'environnement Windows il y a une API pour obtenir le chemin qui exécute un processus. Y a-t-il quelque chose de similaire dans Unix / Linux?

ou y a-t-il une autre façon de faire cela dans ces environnements?

107
demandé sur unwind 2009-03-03 14:35:05

10 réponses

Sur Linux, le lien symbolique /proc/<pid>/exe a le chemin de l'exécutable. Utilisez la commande readlink -f /proc/<pid>/exe pour obtenir la valeur.

sur AIX, ce fichier n'existe pas. Vous pouvez comparer cksum <actual path to binary> et cksum /proc/<pid>/object/a.out .

140
répondu jpalecek 2017-03-06 19:39:54

vous pouvez trouver l'exe facilement par ces moyens, il suffit de l'essayer vous-même.

  • ll /proc/<PID>/exe
  • pwdx <PID>
  • lsof -p <PID> | grep cwd
37
répondu hahakubile 2014-07-01 08:19:54

un peu en retard, 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 */
    size_t buff_len;
    if (buff_len = readlink ("/proc/self/exe", path, dest_len - 1) != -1)
    {
        path [buff_len] = '"151900920"';
        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;
}

modifié: corrigé le bogue signalé par Mark lakata.

26
répondu Hiperion 2018-09-05 13:59:26

j'utilise:

ps -ef | grep 786

remplacer 786 par votre PID ou nom de processus.

10
répondu User 2014-08-02 14:20:02

dans Linux chaque processus a son propre dossier dans /proc . Vous pouvez donc utiliser getpid() pour obtenir le pid du processus en cours d'exécution et ensuite le joindre avec le chemin /proc pour obtenir le dossier dont vous avez besoin.

voici un petit exemple en Python:

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

Voici l'exemple dans ANSI C ainsi:

#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;
}

compiler avec:

gcc -Wall -Werror -g -ansi -pedantic process_path.c -oprocess_path 
4
répondu hyperboreean 2014-04-07 16:31:48

pwdx <process id>

cette commande va récupérer le chemin du processus d'où il est exécuté.

3
répondu gobi 2017-12-22 04:42:51

il n'y a pas de méthode" garanti pour travailler n'importe où".

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 elle a été lancée par un chemin relatif, la même chose se produit (bien que cela nécessite d'obtenir le répertoire de travail courant, en utilisant 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 de l'utilisateur Chemin à partir de l'environnement et passer en revue cela pour voir s'il y a un exécutable binaire approprié avec le même nom.

notez que argv[0] est défini par le processus qui exécute le programme, il n'est donc pas fiable à 100%.

2
répondu Vatine 2009-03-03 11:44:30

merci : Kiwy

avec AIX:

getPathByPid()
{
    if [[ -e /proc//object/a.out ]]; then
        inode=`ls -i /proc//object/a.out 2>/dev/null | awk '{print }'`
        if [[ $? -eq 0 ]]; then
            strnode=${inode}"$"
            strNum=`ls -li /proc//object/ 2>/dev/null | grep $strnode | awk '{print $NF}' | grep "[0-9]\{1,\}\.[0-9]\{1,\}\."`
            if [[ $? -eq 0 ]]; then
                # jfs2.10.6.5869
                n1=`echo $strNum|awk -F"." '{print }'`
                n2=`echo $strNum|awk -F"." '{print }'`
                # brw-rw----    1 root     system       10,  6 Aug 23 2013  hd9var
                strexp="^b.*"$n1,"[[:space:]]\{1,\}"$n2"[[:space:]]\{1,\}.*$"   # "^b.*10, \{1,\}5 \{1,\}.*$"
                strdf=`ls -l /dev/ | grep $strexp | awk '{print $NF}'`
                if [[ $? -eq 0 ]]; then
                    strMpath=`df | grep $strdf | awk '{print $NF}'`
                    if [[ $? -eq 0 ]]; then
                        find $strMpath -inum $inode 2>/dev/null
                        if [[ $? -eq 0 ]]; then
                            return 0
                        fi
                    fi
                fi
            fi
        fi
    fi
    return 1
}
2
répondu zirong 2017-04-13 12:36:30

vous pouvez aussi obtenir le chemin sur GNU / Linux avec (non testé en profondeur):

char file[32];
char buf[64];
pid_t pid = getpid();
sprintf(file, "/proc/%i/cmdline", pid);
FILE *f = fopen(file, "r");
fgets(buf, 64, f);
fclose(f);

si vous voulez le répertoire de l'exécutable Pour peut-être changer le répertoire de travail au répertoire du processus (pour les médias/données/etc), vous devez tout laisser tomber après le dernier/:

*strrchr(buf, '/') = '"151910920"';
/*chdir(buf);*/
1
répondu Jimmio92 2012-05-12 17:33:57

trouver le chemin vers un nom de processus

#!/bin/bash
# @author Lukas Gottschall
PID=`ps aux | grep precessname | grep -v grep | awk '{ print  }'`
PATH=`ls -ald --color=never /proc/$PID/exe | awk '{ print  }'`
echo $PATH
-1
répondu DwD 2011-10-28 16:00:00