كيف يمكنني الحصول على مسار عملية في يونكس / لينكس
-
03-07-2019 - |
سؤال
في بيئة ويندوز هناك API للحصول على المسار الذي يتم تشغيل العملية.هل هناك شيء مماثل في يونكس / لينكس ؟
أو هل هناك طريقة أخرى للقيام بذلك في هذه البيئات?
المحلول
في لينكس، و/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
قليلا في وقت متأخر ، ولكن كل الإجابات كانت محددة لينكس.
إذا كنت في حاجة أيضا 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;
}
تحرير: إصلاح الخلل ذكرت من قبل مارك lakata.
وأنا استخدم:
ps -ef | grep 786
واستبدال 786 مع اسمك PID أو عملية.
وpwdx <process id>
وهذا الأمر سوف جلب مسار العملية من حيث يتم تنفيذ.
في لينكس كل عملية لها المجلد الخاص به في /proc
. لذلك يمكن أن تستخدم getpid()
للحصول على معرف المنتج من عملية تشغيل ومن ثم الانضمام اليها مع /proc
مسار للحصول على المجلد تحتاج نأمل.
وهنا مثال قصيرة في بيثون:
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
}
ويمكنك أيضا الحصول على المسار على جنو / لينكس مع (وليس اختبارها بدقة):
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);*/
وبحث الأمر أدناه للحصول على اسم عملية في قائمة عملية التشغيل، وإعادة توجيه معرف المنتج إلى pwdx القيادة للعثور على مكان العملية.
ps -ef | grep "abc" |grep -v grep| awk '{print $2}' | xargs pwdx
ويستعاض عن عبارة "اي بي سي" مع نمط محدد.
وبدلا من ذلك، إذا كنت قد تكوينه بوصفها وظيفة في .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