Вопрос

В среде Windows существует API для получения пути, по которому запущен процесс.Есть ли что-то подобное в Unix/Linux?

Или есть какой-то другой способ сделать это в этих условиях?

Это было полезно?

Решение

В Linux символическая ссылка /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.

Если вам нужен еще и unix, то вам нужно это:

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

ОТРЕДАКТИРОВАНО: Исправлена ​​ошибка, о которой сообщил Марк Лаката.

Я использую:

ps -ef | grep 786

Замените 786 своим PID или именем процесса.

pwdx <process id>

Эта команда получит путь к процессу, из которого он выполняется.

В Linux у каждого процесса есть своя папка. /proc.Таким образом, вы можете использовать getpid() чтобы получить pid запущенного процесса, а затем присоединиться к нему по пути /proc чтобы получить папку, которая вам, надеюсь, нужна.

Вот краткий пример на Python:

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

Вот пример в 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;
}

Скомпилируйте его с помощью:

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

Не существует метода «гарантированной работы где угодно».

Шаг 1 — проверить argv[0], если программа была запущена по полному пути, то (обычно) будет указан полный путь.Если он был запущен по относительному пути, то же самое сохраняется (хотя для этого необходимо получить текущий рабочий каталог с помощью getcwd().

Шаг 2, если ничего из вышеперечисленного не выполняется, нужно получить имя программы, затем получить имя программы из argv[0], затем получить PATH пользователя из среды и просмотреть его, чтобы увидеть, есть ли подходящий исполняемый двоичный файл с тем же именем.

Обратите внимание, что argv[0] устанавливается процессом, выполняющим программу, поэтому он не является надежным на 100%.

Спасибо : Киви
с 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
}

Вы также можете получить путь в GNU/Linux с помощью (не тщательно проверено):

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

Если вам нужен каталог исполняемого файла для возможного изменения рабочего каталога на каталог процесса (для носителей/данных/и т. д.), вам нужно удалить все после последнего /:

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

Приведенная ниже команда ищет имя процесса в списке запущенных процессов и перенаправляет команду pid на pwdx, чтобы найти местоположение процесса.

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

Замените «abc» на свой конкретный шаблон.

Альтернативно, если вы можете настроить его как функцию в .bashrc, вам может пригодиться его использование, если вам нужно часто его использовать.

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

Например:

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

18404: /home2/Avro/NIFI

Надеюсь, это кому-нибудь когда-нибудь поможет.....

Найдите путь к имени процесса

#!/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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top