Question

Dans l’environnement Windows, une API permet d’obtenir le chemin d’exécution d’un processus. Existe-t-il quelque chose de similaire sous Unix / Linux?

Ou existe-t-il un autre moyen de le faire dans ces environnements?

Était-ce utile?

La solution

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

Sous AIX, ce fichier n'existe pas. Vous pouvez comparer cksum <actual path to binary> et cksum /proc/<pid>/object/a.out.

Autres conseils

Vous pouvez facilement trouver le fichier exe de cette façon, essayez-le 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 également besoin d'unix, 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] = '\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;
}

MODIFIÉ: : correction du bogue signalé par Mark Lakata.

j'utilise:

ps -ef | grep 786

Remplacez 786 par votre PID ou nom de processus.

pwdx <process id>

Cette commande va chercher le chemin du processus à partir duquel il s'exécute.

Sous Linux, chaque processus a son propre dossier dans /proc. Vous pouvez donc utiliser getpid() pour obtenir le pid du processus en cours, puis le joindre au chemin <=> pour obtenir le dossier dont vous avez besoin, espérons-le.

Voici un court exemple en Python:

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

Voici également l'exemple 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;
}

Compilez-le avec:

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

Il n'y a pas de " garantie de travailler n'importe où " méthode.

L'étape 1 consiste à vérifier argv [0]. Si le programme a été démarré par son chemin complet, il aurait (généralement) le chemin complet. Si elle a été démarrée par un chemin relatif, la même chose s’applique (bien que cela nécessite l’obtention du répertoire de travail actuel, en utilisant getcwd ().

L'étape 2, si rien de ce qui précède ne se vérifie, consiste à obtenir le nom du programme, puis le nom du programme dans argv [0], puis le PATH de l'utilisateur depuis l'environnement et examinez-le pour voir si il existe un binaire exécutable approprié du 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/$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
}

Vous pouvez également obtenir le chemin sous GNU / Linux avec (non complètement testé):

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 que le répertoire de l'exécutable soit éventuellement remplacé par le répertoire de travail (pour media / data / etc), vous devez tout supprimer après le dernier /:

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

La commande ci-dessous recherche le nom du processus dans la liste des processus en cours et redirige le pid en pwdx pour rechercher l'emplacement du processus.

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

Remplacer " abc " avec votre modèle spécifique.

Alternativement, si vous pouviez le configurer comme une fonction dans .bashrc, vous pourriez le trouver pratique à utiliser si vous avez besoin que cela soit utilisé fréquemment.

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

Par exemple:

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

18404: /home2/Avro/NIFI

J'espère que cela aidera quelqu'un de temps en temps .....

Recherchez le chemin d'accès à un nom de processus

#!/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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top