In der Windows-Umgebung gibt es eine API, um den Pfad zu ermitteln, der einen Prozess ausführt. Gibt es etwas Ähnliches in Unix/Linux?
Oder gibt es eine andere Möglichkeit, dies in diesen Umgebungen zu tun?
Unter Linux hat der Symlink /proc/<pid>/exe
den Pfad der ausführbaren Datei. Verwenden Sie den Befehl readlink -f /proc/<pid>/exe
, um den Wert abzurufen.
Unter AIX ist diese Datei nicht vorhanden. Sie könnten cksum <actual path to binary>
und cksum /proc/<pid>/object/a.out
vergleichen.
Sie können das Exe auf diese Weise leicht finden, probieren Sie es einfach selbst aus.
ll /proc/<PID>/exe
pwdx <PID>
lsof -p <PID> | grep cwd
Ein bisschen spät, aber alle Antworten waren spezifisch für Linux.
Wenn Sie auch Unix benötigen, brauchen Sie Folgendes:
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;
}
EDITED: Der von Mark Lakata gemeldete Fehler wurde behoben.
Ich benutze:
ps -ef | grep 786
Ersetzen Sie 786 durch Ihre PID oder Ihren Prozessnamen.
pwdx <process id>
Dieser Befehl ruft den Prozesspfad ab, von dem aus er ausgeführt wird.
In Linux hat jeder Prozess einen eigenen Ordner in /proc
. Sie können also getpid()
verwenden, um die PID des laufenden Prozesses abzurufen, und dann den Pfad /proc
eingeben, um den Ordner zu erhalten, den Sie hoffentlich benötigen.
Hier ist ein kurzes Beispiel in Python:
import os
print os.path.join('/proc', str(os.getpid()))
Hier ist auch das Beispiel in 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;
}
Kompilieren Sie es mit:
gcc -Wall -Werror -g -ansi -pedantic process_path.c -oprocess_path
vielen Dank : Kiwy
mit 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
}
Es gibt keine "garantiert überall arbeiten" -Methode.
Schritt 1 besteht darin, argv [0] zu überprüfen. Wenn das Programm mit seinem vollständigen Pfad gestartet wurde, hätte dies (normalerweise) den vollständigen Pfad. Wenn es von einem relativen Pfad aus gestartet wurde, gilt dasselbe (obwohl dazu das aktuelle Arbeitsverzeichnis mit getcwd () abgerufen werden muss.
Schritt 2: Wenn keiner der oben genannten Punkte zutrifft, muss der Name des Programms abgerufen werden, dann wird der Name des Programms von argv [0] abgerufen. Anschließend wird der PATH des Benutzers aus der Umgebung abgerufen ausführbare Binärdatei mit demselben Namen.
Beachten Sie, dass argv [0] von dem Prozess festgelegt wird, der das Programm ausführt, und daher nicht 100% zuverlässig ist.
Sie können den Pfad unter GNU/Linux auch mit (nicht gründlich getestet) erhalten:
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);
Wenn Sie möchten, dass das Verzeichnis der ausführbaren Datei möglicherweise das Arbeitsverzeichnis in das Prozessverzeichnis (für media/data/etc) ändert, müssen Sie alles nach dem letzten/löschen:
*strrchr(buf, '/') = '\0';
/*chdir(buf);*/
Der folgende Befehl sucht nach dem Namen des Prozesses in der laufenden Prozessliste und leitet die PID an den Befehl pwdx weiter, um die Position des Prozesses zu ermitteln.
ps -ef | grep "abc" |grep -v grep| awk '{print $2}' | xargs pwdx
Ersetzen Sie "abc" durch Ihr spezifisches Muster.
Wenn Sie es als Funktion in .bashrc konfigurieren könnten, können Sie es als nützlich erachten, wenn Sie es häufig benötigen.
ps1() { ps -ef | grep "$1" |grep -v grep| awk '{print $2}' | xargs pwdx; }
Für zB:
[[email protected]:/home2/Avro/AvroGen]$ ps1 nifi
18404: /home2/Avro/NIFI
Hoffe das hilft jemandem irgendwann .....