2009-03-03 16 views

Répondre

124

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.

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

+1

'sudo' si la sortie est vide, certains processus sont créés par d'autres utilisateurs du système. – Lun4i

4

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 au chemin /proc pour obtenir le dossier dont vous avez besoin.

Voici un court exemple en Python:

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

Voici l'exemple en C ANSI 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 
+0

bien, mais j'ai besoin de l'utilisation C ANSI. Réservoirs – lsalamon

+0

de sortie Python sur une version récente d'Ubuntu: >>> import os >>> print os.path.join ('/ proc', str (os.getpid())) /proc/24346 –

2

Il n'y a pas « garanti à travailler n'importe où "méthode.

Étape 1 est de vérifier argv [0], si le programme a été lancé par son chemin complet, ce serait (en général) ont le chemin complet. Si elle a été démarrée par un chemin relatif, la même chose vaut (bien que cela nécessite l'obtention du répertoire de travail actuel, en utilisant getcwd().)

L'étape 2, si rien de tout ce qui précède, ne permet d'obtenir le nom du programme, Ensuite, récupérez le nom du programme à partir de argv [0], puis récupérez le PATH de l'utilisateur à partir de l'environnement pour voir s'il existe un binaire exécutable avec le même nom

Notez que argv [0] est défini par le processus qui execs du programme, il est donc pas fiable à 100%.

26

NOTE dE lA RÉDACTIONle code ci-dessous a un bug. readlink ne le fait pas n La chaîne de sortie est terminée, donc si ça marche, c'est un accident.

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

Si vous avez besoin aussi unix, alors vous avez besoin 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; 
} 
+0

Merci pour partager Hiperion, mais j'avais besoin de spécifier un PID et obtenir son chemin d'exe, est-ce possible avec ce code? – Noitidart

+1

@Noitidart - remplacer '"/proc/self/exe "' par 'sprintf (foo,"/proc /% d/exe ", pid)' –

+1

Veuillez noter que readlink ne termine pas le résultat, donc ce code a comportement indéfini. –

-1

Trouver le chemin vers un nom de processus

#!/bin/bash 
# @author Lukas Gottschall 
PID=`ps aux | grep precessname | grep -v grep | awk '{ print $2 }'` 
PATH=`ls -ald --color=never /proc/$PID/exe | awk '{ print $10 }'` 
echo $PATH 
+4

S'il vous plaît expliquer votre code. Si vous l'avez copié et collé depuis un autre endroit, veuillez le lier à la source. – Tim

+0

Ce que ce code n'est pas si efficace est d'obtenir le nom du processus (essentiellement, la ligne "PID" remplace "pgrep"); dans la ligne suivante, il obtient le chemin du binaire en cours d'exécution ('/ proc/$ PID/exe' est un lien symbolique vers le fichier exécutable); et enfin, il fait écho à ce lien symbolique. – Enrico

1

Vous pouvez également obtenir le chemin sur GNU/Linux avec (pas à fond testé):

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 éventuellement changer le répertoire de travail pour le proces répertoire de s (pour les médias/données/etc), vous devez tout laisser tomber après la dernière /:

*strrchr(buf, '/') = '\0'; 
/*chdir(buf);*/ 
26

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

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

J'utilise:

ps -ef | grep 786 

Remplacer 786 avec votre PID ou le nom de processus.

2

remerciements: Kiwy
avec AIX:

getPathByPid() 
{ 
    if [[ -e /proc/$1/object/a.out ]]; then 
     inode=`ls -i /proc/$1/object/a.out 2>/dev/null | awk '{print $1}'` 
     if [[ $? -eq 0 ]]; then 
      strnode=${inode}"$" 
      strNum=`ls -li /proc/$1/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 $2}'` 
       n2=`echo $strNum|awk -F"." '{print $3}'` 
       # 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 
} 
+0

Bien que quelqu'un en ait fait un script – Kiwy

0

pwdx <process id>

Cette commande va chercher le chemin de processus d'où il est en cours d'exécution.

+0

La question concerne l'API pour obtenir des informations, mais merci quand même. – lsalamon