Frage

In Windows-Umgebung gibt es eine API, um den Pfad zu erhalten, die einen Prozess ausgeführt wird. Gibt es etwas ähnliches in Unix / Linux?

Oder gibt es eine andere Art und Weise in diesen Umgebungen zu tun?

War es hilfreich?

Lösung

Unter Linux hat die Symlink /proc/<pid>/exe den Pfad der ausführbaren Datei. Verwenden Sie den Befehl readlink -f /proc/<pid>/exe, um den Wert zu erhalten.

Unter AIX diese Datei nicht existiert. Sie könnten cksum <actual path to binary> und cksum /proc/<pid>/object/a.out vergleichen.

Andere Tipps

Sie können die exe finden leicht von diesen Möglichkeiten, probieren Sie es einfach selbst.

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

Ein wenig spät, aber alle Antworten waren spezifisch für Linux.

Wenn Sie auch Unix benötigen, dann müssen Sie diese:

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:. die von Mark Lakata berichtete Fehler behoben

ich benutze:

ps -ef | grep 786

Ersetzen Sie 786 mit PID oder Prozessnamen.

pwdx <process id>

Mit diesem Befehl wird der Prozess Pfad von holen, wo es ausgeführt wird.

In Linux jeden Prozess hat seinen eigenen Ordner in /proc. So könnte man getpid() verwenden, um die pid des laufenden Prozesses zu bekommen und kommt dann mit dem Pfad /proc, um den Ordner zu erhalten Sie hoffentlich müssen.

Hier ist ein kurzes Beispiel in Python:

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

Hier ist das Beispiel in ANSI C als auch:

#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 mit:

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

Es gibt keine „garantiert überall arbeiten“ -Methode.

Schritt 1 ist argv [0] zu überprüfen, ob das Programm durch den vollständigen Pfad gestartet wurde, würde dies (in der Regel) den vollständigen Pfad hat. Wenn es von einem relativen Pfad gestartet wurde, das gleiche gilt (obwohl dies erfordert teh aktuelles Arbeitsverzeichnis bekommen, mit getcwd ().

Schritt 2, wenn keine der oben genannten gilt, wird der Name des Programms zu erhalten, erhalten Sie dann den Namen des Programms von argv [0], dann den Pfad des Benutzers erhalten aus der Umgebung und gehen durch das zu sehen, ob gibt es eine geeignete ausführbare Binärdatei mit dem gleichen Namen.

Beachten Sie, dass argv [0] durch den Prozess festgelegt wird, dass das Programm, ausführt, so dass es nicht zu 100% zuverlässig ist.

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
}

können Sie erhalten auch den Weg auf GNU / Linux mit (nicht gründlich getestet):

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 das Verzeichnis der ausführbaren wollen vielleicht das Arbeitsverzeichnis des Verzeichnisses auf den Prozess zu ändern (für Medien / Daten / etc), müssen Sie alles, was nach dem letzten / löschen:

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

Die folgende Befehl Suche nach dem Namen des Prozesses in der laufenden Prozess Liste, und leiten Sie die pid Befehl pwdx den Standort des Prozesses zu finden.

ps -ef | grep "abc" |grep -v grep| awk '{print $2}' | xargs pwdx

Ersetzen "abc" mit Ihrem spezifischen Muster.

Alternativ, wenn Sie es als eine Funktion in Bashrc konfigurieren könnten Sie sich als nützlich finden können, wenn Sie diese benötigen häufig verwendet werden.

ps1() { ps -ef | grep "$1" |grep -v grep| awk '{print $2}' | xargs pwdx; }

Für zB:

[admin@myserver:/home2/Avro/AvroGen]$ ps1 nifi

18404: /home2/Avro/NIFI

Hope, das hilft jemand irgendwann .....

Finden Sie den Pfad zu einem Prozessnamen

#!/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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top