Programing

유닉스 / 리눅스에서 프로세스의 경로를 얻는 방법

lottogame 2020. 7. 11. 09:59
반응형

유닉스 / 리눅스에서 프로세스의 경로를 얻는 방법


Windows 환경에는 프로세스를 실행중인 경로를 얻는 API가 있습니다. 유닉스 / 리눅스에 비슷한 것이 있습니까?

아니면 이러한 환경에서 다른 방법이 있습니까?


Linux에서 symlink /proc/<pid>/exe에는 실행 파일 경로가 있습니다. readlink -f /proc/<pid>/exe값을 얻으려면 명령 사용하십시오 .

AIX에서는이 파일이 존재하지 않습니다. cksum <actual path to binary>비교할 수 cksum /proc/<pid>/object/a.out있습니다.


이 방법으로 exe를 쉽게 찾을 수 있습니다. 직접 시도하십시오.

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

조금 늦었지만 모든 답변은 Linux에만 해당됩니다.

유닉스도 필요하다면 다음이 필요합니다.

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

편집 : Mark lakata가보고 한 버그를 수정했습니다.


나는 사용한다:

ps -ef | grep 786

786을 PID 또는 프로세스 이름으로 바꾸십시오.


pwdx <process id>

이 명령은 실행중인 프로세스 경로를 가져옵니다.


In Linux every process has its own folder in /proc. So you could use getpid() to get the pid of the running process and then join it with the path /proc to get the folder you hopefully need.

Here's a short example in Python:

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

Here's the example in ANSI C as well:

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

Compile it with:

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

There's no "guaranteed to work anywhere" method.

Step 1 is to check argv[0], if the program was started by its full path, this would (usually) have the full path. If it was started by a relative path, the same holds (though this requires getting teh current working directory, using getcwd().

Step 2, if none of the above holds, is to get the name of the program, then get the name of the program from argv[0], then get the user's PATH from the environment and go through that to see if there's a suitable executable binary with the same name.

Note that argv[0] is set by the process that execs the program, so it is not 100% reliable.


thanks : Kiwy
with 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
}

You can also get the path on GNU/Linux with (not thoroughly tested):

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

If you want the directory of the executable for perhaps changing the working directory to the process's directory (for media/data/etc), you need to drop everything after the last /:

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

The below command search for the name of the process in the running process list,and redirect the pid to pwdx command to find the location of the process.

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

Replace "abc" with your specific pattern.

Alternatively, if you could configure it as a function in .bashrc, you may find in handy to use if you need this to be used frequently.

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

For eg:

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

18404: /home2/Avro/NIFI

Hope this helps someone sometime.....


Find the path to a process name

#!/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

참고URL : https://stackoverflow.com/questions/606041/how-do-i-get-the-path-of-a-process-in-unix-linux

반응형