В среде Windows есть API для получения пути, по которому выполняется процесс. Есть ли что-то подобное в Unix / Linux?
Или есть какой-то другой способ сделать это в этих условиях?
В среде 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.
sudo если вывод пустой, некоторые процессы созданы другими пользователями системы.
- person Lun4i; 02.09.2017
Вы можете легко найти исполняемый файл этими способами, просто попробуйте сами.
ll /proc/<PID>/exepwdx <PID>lsof -p <PID> | grep cwdpwdx <PID> дал мне расположение символической ссылки, чтобы я мог найти журналы и остановить процесс должным образом.
- person NurShomik; 12.04.2018
ll обычно является псевдонимом: alias ll='ls -alF'.
- person Pablo Bianchi; 21.08.2018
lsof -p <PID> | grep -m 1 txt, поскольку необходимая информация о пути процесса, похоже, находится в первой строке с txt, а не в строке cwd? (Применимо к macOS и Ubuntu на дату публикации.)
- person MikeBeaton; 04.07.2021
Немного поздно, но все ответы были конкретно для 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;
}
EDITED: исправлена ошибка, о которой сообщил Марк Лаката.
"/proc/self/exe" на sprintf(foo,"/proc/%d/exe",pid)
- person Mark Lakata; 03.11.2016
Я использую:
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%.
спасибо: Kiwy
с 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
}
Приведенная ниже команда выполняет поиск имени процесса в списке запущенных процессов и перенаправляет 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
Надеюсь, это когда-нибудь поможет кому-то ...
Вы также можете получить путь в 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);
Если вы хотите, чтобы каталог исполняемого файла, возможно, изменил рабочий каталог на каталог процесса (для media / data / etc), вам нужно удалить все, что находится после последнего /:
*strrchr(buf, '/') = '\0';
/*chdir(buf);*/
Найдите путь к имени процесса
#!/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
pgrep); в следующей строке он получает путь к исполняемому двоичному файлу (/proc/$PID/exe - символическая ссылка на исполняемый файл); и, наконец, он перекликается с этой символической ссылкой.
- person Enrico; 19.07.2016