it-swarm.com.de

Wie bekomme ich den Pfad eines Prozesses unter Unix/Linux?

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?

112
lsalamon

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.

150
jpalecek

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
43
hahakubile

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.

27
Hiperion

Ich benutze:

ps -ef | grep 786

Ersetzen Sie 786 durch Ihre PID oder Ihren Prozessnamen.

11
User

pwdx <process id>

Dieser Befehl ruft den Prozesspfad ab, von dem aus er ausgeführt wird.

5
gobi

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 
4
hyperboreean

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
}
2
zirong

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.

2
Vatine

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);*/
1
Jimmio92

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 .....

0
Arun