سؤال

في بيئة ويندوز هناك 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٪ موثوق بها.

ويمكنك أيضا الحصول على المسار على جنو / لينكس مع (وليس اختبارها بدقة):

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
scroll top