আমি কীভাবে ইউনিক্স / লিনাক্সে কোনও প্রক্রিয়াটির পথ পেতে পারি


138

উইন্ডোজ পরিবেশে একটি প্রক্রিয়া চলছে এমন পথটি পেতে একটি এপিআই রয়েছে। ইউনিক্স / লিনাক্সেও কি তেমন কিছু রয়েছে?

বা এই পরিবেশে এটি করার অন্য কোনও উপায় আছে?

উত্তর:


183

লিনাক্সে, সিমলিংকের /proc/<pid>/exeএক্সিকিউটেবলের পথ রয়েছে। readlink -f /proc/<pid>/exeমান পেতে কমান্ডটি ব্যবহার করুন ।

এআইএক্স-এ, এই ফাইলটির অস্তিত্ব নেই। আপনি তুলনা করতে পারে cksum <actual path to binary>এবং cksum /proc/<pid>/object/a.out


2
sudoযদি আউটপুট ফাঁকা থাকে, অন্য সিস্টেম ব্যবহারকারীদের দ্বারা কিছু প্রক্রিয়া তৈরি করা হয়।
লুন 4i

63

আপনি এই উপায়গুলি দ্বারা সহজেই এক্সকে খুঁজে পেতে পারেন, কেবল এটি নিজের দ্বারা চেষ্টা করুন।

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

1
এটা সত্যিই দারুন. আমি জানতাম যে আমি এটিকে এমন কোনও অবস্থান থেকে চালিয়েছি যার মূল এক্সিকিউটেবলের (বহু সংস্করণের একটির) প্রতীকী লিঙ্ক রয়েছে। pwdx <PID>আমাকে প্রতীকী লিঙ্কের অবস্থান দিয়েছে যাতে আমি লগগুলি সন্ধান করতে পারি এবং সঠিক পদ্ধতিতে প্রক্রিয়াটি থামাতে পারি।
নুরশমিক

1
llসাধারণত উপনাম হল: alias ll='ls -alF'
পাবলো এ

1
শেষ দুটি (pwdx এবং lsof) আপনাকে সঠিক ফলাফল না দিতে পারে। প্রশ্নটি কার্যকর করা কার্যকর পথ সম্পর্কে ছিল path pwdx এবং lsof আপনাকে প্রক্রিয়াটির পাথের পরিবর্তে প্রক্রিয়াটির সিডাব্লুডি দেবে। আমি মনে করি যে জালাপেকের উত্তরটি আরও নির্ভুল কারণ মূল অনুরোধকারী মৃত্যুদন্ড কার্যকর করার বর্ণনকারী সফ্ট লিঙ্কের চেয়ে এক্সিকিউটেবলের পথ চেয়েছিল।
শিমোন

28

কিছুটা দেরি হলেও সমস্ত উত্তরগুলি লিনাক্সের জন্য নির্দিষ্ট ছিল।

আপনার যদি ইউনিক্সও প্রয়োজন হয় তবে আপনার এটি দরকার:

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

সম্পাদনা করা হয়েছে: মার্ক লাকাটা দ্বারা রিপোর্ট করা বাগটি ঠিক করা হয়েছে।


হিপরিওন ভাগ করে নেওয়ার জন্য ধন্যবাদ, তবে আমার একটি পিআইডি নির্দিষ্ট করা এবং এর উদাহরণ পাবার দরকার ছিল, এই কোড দিয়ে কি এটি সম্ভব?
Noitidart

1
@Noitidart - প্রতিস্থাপন "/proc/self/exe"সঙ্গেsprintf(foo,"/proc/%d/exe",pid)
মার্ক Lakata

2
দয়া করে মনে রাখবেন যে রিডলিংক ফলাফলটি বাতিল করে না, সুতরাং এই কোডটির অপরিবর্তিত আচরণ রয়েছে।
লাকাটা

আপনাকে ধন্যবাদ_মার্কলাকাতা! :)
Noitidart

@

14

আমি ব্যবহার করি:

ps -ef | grep 786

আপনার পিআইডি বা প্রক্রিয়া নামের সাথে 786 প্রতিস্থাপন করুন।


11

pwdx <process id>

এই কমান্ডটি যেখানে এটি চালাচ্ছে সেখানে থেকে প্রক্রিয়াটির পথটি আনবে।


প্রশ্নটি তথ্য পাওয়ার জন্য এপিআই সম্পর্কিত, তবে যাইহোক ধন্যবাদ।
lsalamon

4

লিনাক্সে প্রতিটি প্রক্রিয়ার নিজস্ব ফোল্ডার থাকে /proc। সুতরাং আপনি getpid()চলমান প্রক্রিয়াটির পিড পেতে ব্যবহার করতে পারেন এবং তারপরে /procআপনার ফোল্ডারটি প্রত্যাশা করার জন্য পাথের সাথে যোগ দিতে পারেন ।

পাইথনের একটি সংক্ষিপ্ত উদাহরণ এখানে:

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

এখানে এএনএসআই সি-তে উদাহরণ রয়েছে:

#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 

উবুন্টু এর সর্বশেষ সংস্করণটি উপর পাইথন আউটপুট: >>> আমদানি OS >>> মুদ্রণ os.path.join ( 'জন্য / proc', Str (os.getpid ())) জন্য / proc / 24346
লুক স্ট্যানলি

3

"কোথাও কাজ করার গ্যারান্টিযুক্ত" পদ্ধতি নেই।

পদক্ষেপ 1 হ'ল আরগভি [0] যাচাই করা, যদি প্রোগ্রামটি পুরো পথ দিয়ে শুরু করা হয়, তবে এটি (সাধারণত) পুরো পথ পাবে। যদি এটি কোনও আপেক্ষিক পথ দ্বারা শুরু করা হয়, তবে একই হোল্ড (যদিও এটি getcwd () ব্যবহার করে teh বর্তমান ওয়ার্কিং ডিরেক্টরি পেতে প্রয়োজন।

পদক্ষেপ 2, যদি উপরেরগুলির কোনওটির কাছে প্রোগ্রামটির নাম না রাখা হয়, তবে প্রোগ্রামটির নামটি আর্গভি [0] থেকে পেয়ে যান, তারপরে পরিবেশের থেকে ব্যবহারকারীর পাথ পান এবং সেখানে কোনও উপযুক্ত আছে কিনা তা দেখতে যান একই নামে এক্সিকিউটেবল বাইনারি।

নোট করুন যে আরগভি [0] প্রোগ্রামটি কার্যকর করে এমন প্রক্রিয়া দ্বারা সেট করা হয়, সুতরাং এটি 100% নির্ভরযোগ্য নয়।


2

ধন্যবাদ: এআইএক্সের
সাথে কিউই :

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
}

এই যে কেউ এর স্ক্রিপ্ট তৈরি করেছে
কিউই

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

1

চলমান প্রক্রিয়া তালিকায় নীচের কমান্ডটি প্রক্রিয়াটির নাম অনুসন্ধান করে এবং প্রক্রিয়াটির অবস্থান অনুসন্ধানের জন্য পিডিকে 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

আশা করি এটি কারওর মাঝে সাহায্য করবে .....


-1

একটি প্রক্রিয়া নামের পাথ সন্ধান করুন

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

4
আপনার কোড ব্যাখ্যা করুন। আপনি যদি অন্য কোথাও এটি অনুলিপি করে আটকে দেন তবে অনুগ্রহ করে উত্সটিতে লিঙ্ক করুন।
টিম

এই-এত দক্ষ নয়-কোডটি কী করছে তা প্রক্রিয়াটির নাম পাচ্ছে (মূলত, "পিআইডি" লাইনটি এর প্রতিস্থাপন pgrep); পরের লাইনে এটি বাইনারি কার্যকর হওয়ার পথ পায় ( /proc/$PID/exeএক্সিকিউটেবল ফাইলের একটি সিমলিংক); এবং অবশেষে এটি প্রতিধ্বনি করে
এনরিকো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.