¿Cómo obtengo la ruta de un proceso en Unix/Linux?
-
03-07-2019 - |
Pregunta
En entorno Windows existe una API para obtener la ruta por la que se ejecuta un proceso.¿Existe algo similar en Unix/Linux?
¿O hay alguna otra forma de hacerlo en estos entornos?
Solución
En Linux, el enlace simbólico /proc/<pid>/exe
tiene la ruta del ejecutable.usa el comando readlink -f /proc/<pid>/exe
para obtener el valor.
En AIX, este archivo no existe.Podrías comparar cksum <actual path to binary>
y cksum /proc/<pid>/object/a.out
.
Otros consejos
Puede encontrar el exe fácilmente de esta manera, simplemente pruébelo usted mismo.
ll /proc/<PID>/exe
pwdx <PID>
lsof -p <PID> | grep cwd
Un poco tarde, pero todas las respuestas fueron específicas para Linux.
Si necesita también unix, entonces 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 */
size_t buff_len;
if (buff_len = readlink ("/proc/self/exe", path, dest_len - 1) != -1)
{
path [buff_len] = '\0';
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;
}
EDITADO: Se corrigió el error reportado por Mark lakata.
Yo uso:
ps -ef | grep 786
Reemplace 786 con su PID o nombre de proceso.
pwdx <process id>
Este comando buscará la ruta del proceso desde donde se está ejecutando.
En Linux cada proceso tiene su propia carpeta en /proc
. Por lo tanto, puede usar getpid()
para obtener el pid del proceso en ejecución y luego unirlo con la ruta <=> para obtener la carpeta que, con suerte, necesitará.
Aquí hay un breve ejemplo en Python:
import os
print os.path.join('/proc', str(os.getpid()))
Aquí también está el ejemplo 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;
}
Compilarlo con:
gcc -Wall -Werror -g -ansi -pedantic process_path.c -oprocess_path
No hay " garantizado para trabajar en cualquier lugar " método.
El paso 1 es verificar argv [0], si el programa se inició por su ruta completa, esto (generalmente) tendría la ruta completa. Si se inició por una ruta relativa, se mantiene lo mismo (aunque esto requiere obtener el directorio de trabajo actual, usando getcwd ().
El paso 2, si no se cumple ninguno de los anteriores, es obtener el nombre del programa, luego obtener el nombre del programa de argv [0], luego obtener la RUTA del usuario del entorno y revisar eso para ver si hay un binario ejecutable adecuado con el mismo nombre.
Tenga en cuenta que argv [0] está configurado por el proceso que ejecuta el programa, por lo que no es 100% confiable.
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
}
También puede obtener la ruta en GNU / Linux con (no probado exhaustivamente):
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 el directorio del ejecutable para quizás cambiar el directorio de trabajo al directorio del proceso (para medios / datos / etc.), debe soltar todo después del último /:
*strrchr(buf, '/') = '\0';
/*chdir(buf);*/
El siguiente comando busca el nombre del proceso en la lista de procesos en ejecución y redirige el comando pid a pwdx para encontrar la ubicación del proceso.
ps -ef | grep "abc" |grep -v grep| awk '{print $2}' | xargs pwdx
Reemplazar " abc " con tu patrón específico.
Alternativamente, si puede configurarlo como una función en .bashrc, puede ser útil si lo necesita con frecuencia.
ps1() { ps -ef | grep "$1" |grep -v grep| awk '{print $2}' | xargs pwdx; }
Por ejemplo:
[admin@myserver:/home2/Avro/AvroGen]$ ps1 nifi
18404: /home2/Avro/NIFI
Espero que esto ayude a alguien alguna vez .....
Encuentra la ruta 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