Comment obtenir le chemin d'un processus dans Unix / Linux
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
.
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
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.
j'utilise:
ps -ef | grep 786
remplacer 786 par votre PID ou nom de processus.
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
pwdx <process id>
cette commande va récupérer le chemin du processus d'où il est exécuté.
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%.
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
}
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);*/
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