PS: আমি কীভাবে কোনও প্রদত্ত পিডের জন্য সমস্ত শিশু প্রক্রিয়া পুনরাবৃত্তভাবে পেতে পারি


43

আমি কীভাবে পুরো প্রক্রিয়া গাছটিকে একটি গাছ হিসাবে প্রদর্শিত এবং কেবলমাত্র সেই গাছ অর্থাৎ অন্য কোনও প্রক্রিয়া দ্বারা প্রসারণ করতে পারি?

আউটপুট যেমন দেখতে পারে

 4378 ?        Ss     0:10 SCREEN
 4897 pts/16   Ss     0:00  \_ -/bin/bash
25667 pts/16   S+     0:00  |   \_ git diff
25669 pts/16   S+     0:00  |       \_ less -FRSX
11118 pts/32   Ss+    0:00  \_ -/bin/bash
11123 pts/32   S+     0:00      \_ vi

আমি কাঙ্ক্ষিত ফলাফল বিশুদ্ধরূপে করার পরামিতি সঙ্গে পাই নি ps

নিম্নলিখিতগুলি কাঙ্ক্ষিত ফলাফল দেয় তবে কিছুটা জড়িত বলে মনে হচ্ছে:

#!/bin/bash

pidtree() {
  echo -n $1 " "
  for _child in $(ps -o pid --no-headers --ppid $1); do
    echo -n $_child `pidtree $_child` " "
  done
}

ps f `pidtree 4378`

কারও কি সহজ সমাধান আছে?


কোনও উত্তর নয়, তবে দিয়ে শুরু করুন ps auxf
jftuga

3
@ জেটিফুগা আসলে এটি যেখানে আমি শুরু করেছি, তবে এটি আমাকে সমস্ত প্রক্রিয়া দেয় যা আমি চাই না exactly
কিনান

উত্তর:


38

pstreeএকটি খুব ভাল সমাধান, কিন্তু এটা একটি সামান্য বিট স্বল্পভাষী হয়। আমি ps --forestপরিবর্তে ব্যবহার । তবে এটি PID( -p) এর জন্য নয় কারণ এটি কেবলমাত্র নির্দিষ্ট প্রক্রিয়াটি প্রিন্ট করে, তবে সেশনের জন্য ( -g)। এটি কোনও তথ্য ছাপতে পারে কোনও psপছন্দসই ASCII আর্ট ট্রিে -oবিকল্পটি নির্ধারণ করে মুদ্রণ করতে পারে ।

সুতরাং এই সমস্যার জন্য আমার পরামর্শ:

ps --forest -o pid,tty,stat,time,cmd -g 2795

প্রক্রিয়াটি যদি সেশন লিডার না হয় তবে আরও কিছুটা কৌশল প্রয়োগ করতে হবে:

ps --forest -o pid,tty,stat,time,cmd -g $(ps -o sid= -p 2795)

এটি প্রথমে বর্তমান প্রক্রিয়ার সেশন আইডি (এসআইডি) পায় এবং তারপরে সেই এসিডের সাথে আবার পিএস কল করে।

কলামের শিরোনামগুলির প্রয়োজন না হলে '-o' বিকল্পগুলিতে প্রতিটি কলাম সংজ্ঞা দেওয়ার পরে একটি '=' যুক্ত করুন:

ps --forest -o pid=,tty=,stat=,time=,cmd= -g $(ps -o sid= -p 2795)

একটি উদাহরণ রান এবং ফলাফল:

$ ps --forest -o pid=,tty=,stat=,time=,cmd= -g $(ps -o sid= -p 30085)
27950 pts/36   Ss   00:00:00 -bash
30085 pts/36   S+   00:00:00  \_ /bin/bash ./loop.sh
31888 pts/36   S+   00:00:00      \_ sleep 5

দুর্ভাগ্যক্রমে screenএটি কাজ করে না কারণ এটি প্রতিটি চাইল্ড স্ক্রিন এবং সমস্ত নাতনি বাশের জন্য সিড সেট করে।

কোনও প্রক্রিয়া দ্বারা উদ্ভূত সমস্ত প্রক্রিয়াগুলি পেতে পুরো গাছটি তৈরি করা দরকার। আমি এর জন্য ব্যবহার করেছি। প্রথমে এটিগুলিকে ধারণ করার জন্য একটি হ্যাশ অ্যারে তৈরি করে PID => ,child,child...। শেষে এটি প্রদত্ত প্রক্রিয়াটির সমস্ত শিশু প্রক্রিয়া নিষ্কাশনের জন্য একটি পুনরাবৃত্ত ফাংশন কল করে। ফলাফলটি psবিন্যাস করতে অন্যটিতে পাস করা হয় । আসল পিআইডি এর পরিবর্তে আর্গুমেন্ট হিসাবে লিখতে হবে <PID>:

ps --forest $(ps -e --no-header -o pid,ppid|awk -vp=<PID> 'function r(s){print s;s=a[s];while(s){sub(",","",s);t=s;sub(",.*","",t);sub("[0-9]+","",s);r(t)}}{a[$2]=a[$2]","$1}END{r(p)}')

একটি স্ক্রিন প্রক্রিয়া (পিড = 8041) এর জন্য উদাহরণ আউটপুটটি দেখতে এমন দেখাচ্ছে:

  PID TTY      STAT   TIME COMMAND
 8041 ?        Ss     0:00 SCREEN
 8042 pts/8    Ss     0:00  \_ /bin/bash
 8092 pts/8    T      0:00      \_ vim test_arg test_server
12473 pts/8    T      0:00      \_ vim
12972 pts/8    T      0:00      \_ vim

এর সাথে ইস্যুটি (আমি জানি এটি একটি পুরানো উত্তর) - ফরেস্ট বিকল্পটি কেবল লিনাক্সে (বা অন্যান্য gnu ভিত্তিক "পিএস" কমান্ড) এ কাজ করে। সোলারিস, এবং ম্যাকোস এটি পছন্দ করে না।
আরমান্ড

@ ট্রুই ওয়াই আপনি কি এমন কোনও সিআই এপিআই জানেন যা এটি করতে পারে? আপনাকে ধন্যবাদ
Bionix1441

বায়োনিক্স না, দুঃখিত ... আমি সেই গাছটি তৈরির জন্য ডিরেক্টরিগুলি / proc / <PID> পড়তে পারি।
সত্য

1
এটির মতো দেখতে সহজ হওয়া উচিত যদি psকেবলমাত্র একটি পিআইডি-র সমস্ত বংশধরকে ফিল্টার করার জন্য একটি ফিল্টার পতাকা বিকল্প থাকে।
সিএমসিডিগ্রাগনকাই

27
pstree ${pid}

${pid}পিতামাতার প্রক্রিয়াটির পাইডটি কোথায় ।

pstreeজেন্টু লিনাক্স-এ, সম্ভবত "psmisc" প্যাকেজটিতে রয়েছেhttp://psmisc.sourceforge.net/


9
ধন্যবাদ, আমি উল্লেখ করেছিলাম উচিত ছিল যে আমি দেখেছি pstree, তবে আরও ভার্জোজ আউটপুট ফর্ম্যাটটি মিস করেছি। তবে pstree -p <pid>কমপক্ষে কমপক্ষে পিডগুলি মুদ্রণ করুন।
কিনান

2
আমারও এই সমস্যাটি রয়েছে, আমার সমস্ত শিশু পিডগুলি পুনরাবৃত্তভাবে জড়ো করা দরকার তবে আমার কেবল পিডগুলি দরকার, তাই আমার sedসমস্ত কাজ হবে ... মিমি এটি কাজ করে :)pstree -pn 4008 |grep -o "([[:digit:]]*)" |grep -o "[[:digit:]]*"
কুম্ভ শক্তি

12

এখানে আমার সংস্করণটি তাত্ক্ষণিকভাবে চলমান (কারণ psশুধুমাত্র একবারেই কার্যকর করা হয়েছে)। বাশ এবং zsh এ কাজ করে।

pidtree() (
    [ -n "$ZSH_VERSION"  ] && setopt shwordsplit
    declare -A CHILDS
    while read P PP;do
        CHILDS[$PP]+=" $P"
    done < <(ps -e -o pid= -o ppid=)

    walk() {
        echo $1
        for i in ${CHILDS[$1]};do
            walk $i
        done
    }

    for i in "$@";do
        walk $i
    done
)

1
এটি বর্তমান প্রক্রিয়াটির মূদ্রাটিও ছাপে, যা আপনি চাইবেন বা নাও চান। আমি বর্তমান প্রক্রিয়াটি তালিকাভুক্ত করতে চাইনি (কেবলমাত্র বর্তমান প্রক্রিয়ার বংশধর), তাই আমি echo $1লুপের জন্য প্রথমটির ভিতরে গিয়ে স্ক্রিপ্টটি পরিবর্তন করেছি echo $i
লাকাতা

1
যখন আমি এটি পেয়েছিলাম তখন আমি এই জাতীয় একটি ফাংশন লিখতে যাচ্ছিলাম। এটিই একমাত্র সমাধান যা ম্যাকস, লিনাক্স এবং সোলারিসে কাজ করে বলে মনে হচ্ছে। মহান কাজ. মেমরির কাজটি শেষ করতে আপনি যে পিএস এর একক রান উপর ভরসা করেন তা ভালবাসুন।
আরমান্ড

3

আমি পিতামাতার সন্তানের প্রক্রিয়া (এসএস) এর তালিকা পিড তৈরি করতে একটি ছোট বাশ স্ক্রিপ্ট তৈরি করেছি। যতক্ষণ না এটি শেষ শিশু প্রক্রিয়াটি খুঁজে পায় যতক্ষণ না কোনও বাচ্চা নেই। এটি আপনাকে গাছের দর্শন দেয় না। এটি কেবল সমস্ত পিডের তালিকাবদ্ধ করে।

function list_offspring {
  tp=`pgrep -P $1`          #get childs pids of parent pid
  for i in $tp; do          #loop through childs
    if [ -z $i ]; then      #check if empty list
      exit                  #if empty: exit
    else                    #else
      echo -n "$i "         #print childs pid
      list_offspring $i     #call list_offspring again with child pid as the parent
    fi;
  done
}
list_offspring $1

তালিকা_অফস্প্রিংয়ের প্রথম যুক্তি হল প্যারেন্ট পিড


1
ইতিমধ্যে আরও বেশ কয়েকটি উত্তর রয়েছে যা একটি ব্যাশ স্ক্রিপ্ট দেয় যা প্রকৃত গাছ মুদ্রণ করে না, প্রশ্নটিতে নিজেই রয়েছে। আপনার (আংশিক) উত্তরের বিদ্যমান (আংশিক) উত্তরের চেয়ে কী কী সুবিধা রয়েছে?
ডেভিড রিচার্বি

আমি পুনরাবৃত্তি ব্যবহার করেছি এবং কিছু ব্যাখ্যা যুক্ত করেছি। ভেবেছিল এটি কারও সাহায্য করতে পারে। এটি শিরোনাম যা চায় ঠিক তাই করে।
মেরিজন

আমি এখানে pgrep ব্যবহার পছন্দ করি, যেহেতু ইউনিক্স ভেরিয়েন্টগুলির মধ্যে PS পৃথক হতে পারে।
জন Szakmeister

3

ps -H -g "$pid" -o comm

প্রতি সেচ গাছে যোগ করে না, এটি কেবল প্রক্রিয়াগুলির তালিকা।

উদাহরণস্বরূপ দেয়

COMMAND
bash
  nvim
    python

-Hবিকল্প একটি প্রক্রিয়া গাছ বা প্রদর্শন করতে ব্যবহৃত হয় "প্রসেস অনুক্রমের (বন)"
বিচারের জন্য মনিকা - এন্থনি জি

2

আমি ঠিক একই সমস্যার সমাধান খুঁজতে কাজ করে যাচ্ছি। মূলত, পিএইচ ম্যানপেজ কোনও বিকল্প নথি করে না যা আমরা একটি কমান্ড দিয়ে যা করতে চাই তা করতে দেয়। উপসংহার: একটি স্ক্রিপ্ট দরকার।

আমি আপনার সাথে খুব অনুরূপ একটি স্ক্রিপ্ট নিয়ে এসেছি। আমি এটি আমার ~ / .Bashrc এ আটকালাম যাতে আমি এটি কোনও শেল থেকে ব্যবহার করতে পারি।

pidtree() {
  local parent=$1
  local list=
  while [ "$parent" ] ; do     
    if [ -n "$list" ] ; then
      list="$list,$parent"
    else
      list="$parent"
    fi
    parent=$(ps --ppid $parent -o pid h)
  done
  ps -f -p $list f
}

1

কমান্ড-লাইনের পথে:

ps -o time,pid,ppid,cmd --forest -g -p $(pgrep -x bash)

এটি ফলাফল:

    TIME   PID  PPID CMD
00:00:00  5484  5480 bash
00:00:01  5531  5484  \_ emacs -nw .bashrc
00:00:01  2986  2984 /bin/bash
00:00:00  4731  2986  \_ redshift
00:00:00  5543  2986  \_ ps -o time,pid,ppid,cmd --forest -g -p 2986 5484

এই উপায়টির আরও মার্জিত উপায় হল কোনও ফাংশনকে এখানে সংজ্ঞায়িত করা .bashrc:

function subps()                                                                                    
{                                                                                                   
    process=$(pgrep -x $1)                                                                                                                                                                     
    ps -o time,pid,ppid,cmd --forest -g -p $process                                                 
}    

তারপরে কমান্ড-লাইনে রান করুন:

subps bash

1

এটি কেবলমাত্র পিড + বাচ্চাদের এক লাইনে পিড দেয় যা আরও প্রক্রিয়াজাতকরণের জন্য দরকারী।

pidtree() {
    for _pid in "$@"; do
        echo $_pid
        pidtree `ps --ppid $_pid -o pid h`
    done
}

0

ফিলিপের উপরের উপর ভিত্তি করে আমি একই ধরণের স্ক্রিপ্ট তৈরি করেছি

pidlist() {
local thispid=$1
local fulllist=
local childlist=
childlist=$(ps --ppid $thispid -o pid h)
for pid in $childlist
do
  fulllist="$(pidlist $pid) $fulllist"
done
echo "$thispid $fulllist"
}

এটি স্পেস-ডিলিমেটেড ফর্ম্যাটে সমস্ত শিশু, নাতনী ইত্যাদি পিডকে আউটপুট করে। এই হিসাবে, পিএস হিসাবে খাওয়ানো যেতে পারে, হিসাবে

PS -p $ (pidlist PID )


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.