2009-03-03 14 views

Respuesta

124

En Linux, el enlace simbólico /proc/<pid>/exe tiene la ruta del ejecutable. Use el comando readlink -f /proc/<pid>/exe para obtener el valor.

En AIX, este archivo no existe. Puede comparar cksum <actual path to binary> y cksum /proc/<pid>/object/a.out.

+1

'sudo' si la salida está vacía, algunos procesos son creados por otros usuarios del sistema. – Lun4i

4

En Linux, cada proceso tiene su propia carpeta en /proc. De modo que podría usar getpid() para obtener el pid del proceso en ejecución y luego unirlo con la ruta /proc para obtener la carpeta que esperemos necesitar.

Aquí hay un pequeño ejemplo en Python:

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

Aquí está el ejemplo en ANSI C, así:

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

Compilar con:

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

bueno, pero necesito el uso de C ANSI. Tanques – lsalamon

+0

salida Python en una versión reciente de Ubuntu: >>> import os >>> os.path.join print ('/ proc', str (os.getpid())) /proc/24346 –

2

No hay "garantiza que trabajar en cualquier lugar "método.

El paso 1 es comprobar argv [0], si el programa se inició por su ruta completa, esto (por lo general) tendría la ruta completa. Si fue iniciado por una ruta relativa, lo mismo ocurre (aunque esto requiere obtener el directorio de trabajo actual, usando getcwd().

El paso 2, si no se cumple ninguna de las anteriores, es obtener el nombre del programa, luego obtenga el nombre del programa de argv [0], luego obtenga la ruta del usuario del entorno y revise si hay un binario ejecutable adecuado con el mismo nombre.

Tenga en cuenta que argv [0] está configurado por el proceso que los ejecutivos del programa, por lo que no es 100% fiable.

26

NOTA dEL EDITORel código de abajo tiene un error. readlink no lo hace n ull termina la cadena de salida, por lo que si funciona, fue un accidente.

Un poco tarde, pero todas las respuestas fueron específicas de linux.

Si necesita también Unix, entonces usted necesita esto:

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

Gracias para compartir Hiperion, pero necesitaba especificar un PID y obtener su ruta exe, ¿es posible con este código? – Noitidart

+1

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

+1

Tenga en cuenta que readlink no anula el resultado, por lo que este código tiene comportamiento indefinido –

-1

encontrar el camino a un nombre de proceso

#!/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

Por favor explique su código. Si lo copia y lo pega de otro lugar, enlace a la fuente. – Tim

+0

Lo que este código no tan eficiente está haciendo es obtener el nombre del proceso (esencialmente, la línea "PID" reemplaza a 'pgrep'); en la siguiente línea obtiene la ruta del binario que se está ejecutando ('/ proc/$ PID/exe' es un enlace simbólico al archivo ejecutable); y finalmente se hace eco de ese enlace simbólico. – Enrico

1

También puede obtener la ruta en GNU/Linux con (si no está completamente probado):

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 desea que el directorio del ejecutable tal vez cambie el directorio de trabajo para el proceso directorio de s (para medios de comunicación/datos/etc), tiene que dejar todo después de la última /:

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

se puede encontrar el exe fácilmente por estas formas, a modo de prueba usted mismo.

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

que utilizo:

ps -ef | grep 786 

Reemplazar 786 con su PID o nombre del proceso.

2

gracias: Kiwy
con 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

Bueno, alguien hizo una secuencia de comandos – Kiwy

0

pwdx <process id>

Este comando buscará la ruta de proceso desde donde se está ejecutando.

+0

La pregunta es acerca de la API para obtener información, pero gracias de todos modos. – lsalamon

Cuestiones relacionadas