Pregunta

En entorno Windows existe una API para obtener la ruta por la que se ejecuta un proceso.¿Existe algo similar en Unix/Linux?

¿O hay alguna otra forma de hacerlo en estos entornos?

¿Fue útil?

Solución

En Linux, el enlace simbólico /proc/<pid>/exe tiene la ruta del ejecutable.usa el comando readlink -f /proc/<pid>/exe para obtener el valor.

En AIX, este archivo no existe.Podrías comparar cksum <actual path to binary> y cksum /proc/<pid>/object/a.out.

Otros consejos

Puede encontrar el exe fácilmente de esta manera, simplemente pruébelo usted mismo.

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

Un poco tarde, pero todas las respuestas fueron específicas para Linux.

Si necesita también unix, entonces necesita esto:

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;
}

EDITADO: Se corrigió el error reportado por Mark lakata.

Yo uso:

ps -ef | grep 786

Reemplace 786 con su PID o nombre de proceso.

pwdx <process id>

Este comando buscará la ruta del proceso desde donde se está ejecutando.

En Linux cada proceso tiene su propia carpeta en /proc. Por lo tanto, puede usar getpid() para obtener el pid del proceso en ejecución y luego unirlo con la ruta <=> para obtener la carpeta que, con suerte, necesitará.

Aquí hay un breve ejemplo en Python:

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

Aquí también está el ejemplo 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;
}

Compilarlo con:

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

No hay " garantizado para trabajar en cualquier lugar " método.

El paso 1 es verificar argv [0], si el programa se inició por su ruta completa, esto (generalmente) tendría la ruta completa. Si se inició por una ruta relativa, se mantiene lo mismo (aunque esto requiere obtener el directorio de trabajo actual, usando getcwd ().

El paso 2, si no se cumple ninguno de los anteriores, es obtener el nombre del programa, luego obtener el nombre del programa de argv [0], luego obtener la RUTA del usuario del entorno y revisar eso para ver si hay un binario ejecutable adecuado con el mismo nombre.

Tenga en cuenta que argv [0] está configurado por el proceso que ejecuta el programa, por lo que no es 100% confiable.

gracias:     Kiwy
con 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
}

También puede obtener la ruta en GNU / Linux con (no probado exhaustivamente):

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 desea el directorio del ejecutable para quizás cambiar el directorio de trabajo al directorio del proceso (para medios / datos / etc.), debe soltar todo después del último /:

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

El siguiente comando busca el nombre del proceso en la lista de procesos en ejecución y redirige el comando pid a pwdx para encontrar la ubicación del proceso.

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

Reemplazar " abc " con tu patrón específico.

Alternativamente, si puede configurarlo como una función en .bashrc, puede ser útil si lo necesita con frecuencia.

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

Por ejemplo:

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

18404: /home2/Avro/NIFI

Espero que esto ayude a alguien alguna vez .....

Encuentra la ruta a un nombre de proceso

#!/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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top