মার্জিতভাবে বংশধর প্রক্রিয়াগুলির তালিকা পান


23

আমি যে সমস্ত প্রক্রিয়া অবতরণ করে (যেমন শিশু, পিতামহ, ইত্যাদি) এর একটি তালিকা পেতে চাই $pid। এটি নিয়ে আসা সহজতম উপায়:

pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"

সমস্ত বংশধর প্রক্রিয়াগুলির সম্পূর্ণ তালিকা পাওয়ার জন্য কোনও আদেশ বা কোনও সহজ উপায় আছে ?


আপনার সবগুলি এক লাইনে লাগানোর কোনও কারণ আছে কি? আপনি যে আউটপুট সঙ্গে কি করছেন? আমার অনুভূতি আছে যে এটি একটি এক্সআই সমস্যা, এবং আপনি ভুল প্রশ্ন জিজ্ঞাসা করছেন।
জর্দানম

যতক্ষণ না এটি পরিষ্কার হয় ততক্ষণ আমি ফর্ম্যাটটির বিষয়ে চিন্তা করি না (যেমন আমি '\n'সীমান্তিত বনাম সম্পর্কে ' 'সীমাবদ্ধ নেই)। ব্যবহারিক ব্যবহারের ক্ষেত্রে হ'ল: ক) একটি ডেমোনাইজার স্ক্রিপ্ট আমি খাঁটি ম্যাসোচিজমের বাইরে লিখেছি (বিশেষত, "স্টপ" কার্যকারিতাটি ডেমোনাইজড প্রক্রিয়া দ্বারা উদ্ভূত প্রক্রিয়াগুলির যে কোনও গাছের সাথে মোকাবিলা করতে হবে); এবং খ) একটি টাইমআউট স্ক্রিপ্ট যা টাইম-আউট প্রক্রিয়াটি যা মজাদার তৈরি করেছিল তা মেরে ফেলবে।
STenyaK

2
@ স্টেনিয়াক আপনার ব্যবহারের ঘটনাগুলি আমাকে ভাবতে বাধ্য করে যে আপনি প্রক্রিয়া গোষ্ঠী এবং এর জন্য একটি নেতিবাচক যুক্তি খুঁজছেন kill। দেখুন unix.stackexchange.com/questions/9480/... , unix.stackexchange.com/questions/50555/...
গিলেজ 'SO- স্টপ হচ্ছে মন্দ'

@ গিলস ব্যবহার করে ps ax -opid,ppid,pgrp,cmdআমি দেখতে পাচ্ছি যে অনেকগুলি প্রক্রিয়া রয়েছে যা হ'ল সঠিক সাবট্রির মতোই ভাগ করে নিতে pgrpচাই। (উপরন্তু, আমি দেখতে পারছি না setpgrp: ডেবিয়ান স্থিতিশীল প্যাকেজ যে কোন জায়গায় তালিকাভুক্ত প্রোগ্রাম packages.debian.org/... )
STenyaK

1
আরেকটি ব্যবহারের ক্ষেত্রে: পুরো প্রক্রিয়া গাছের উপর রেনিস / আয়নিস যা প্রচুর সংস্থান গ্রহণ করে, যেমন একটি বৃহত সমান্তরাল বিল্ড।
চিতা

উত্তর:


15

নিম্নলিখিতটি কিছুটা সহজ এবং কমান্ডের নামগুলিতে সংখ্যা উপেক্ষা করার অতিরিক্ত সুবিধা রয়েছে:

pstree -p $pid | grep -o '([0-9]\+)' | grep -o '[0-9]\+'

বা পার্ল সহ:

pstree -p $pid | perl -ne 'print "$1\n" while /\((\d+)\)/g'

আমরা প্রথম বন্ধনীগুলির মধ্যে নম্বরগুলি সন্ধান করছি যাতে আমরা যখন দৌড়ে যাই তখন উদাহরণস্বরূপ 2 টি শিশু প্রক্রিয়া হিসাবে দেই না gif2png(3012)। তবে যদি কমান্ডের নামটিতে একটি প্রথম বন্ধনী যুক্ত থাকে, সমস্ত বেট বন্ধ রয়েছে। এখনও পর্যন্ত কেবল পাঠ্য প্রক্রিয়াজাতকরণ আপনাকে নিতে পারে।

সুতরাং আমি আরও মনে করি যে প্রক্রিয়া গ্রুপগুলি যাওয়ার উপায় to আপনি যদি তার নিজস্ব প্রক্রিয়া গোষ্ঠীতে কোনও প্রক্রিয়া চালাতে চান তবে আপনি ডিবান প্যাকেজ 'ডিমনটোউলস' থেকে 'পিগ্রাফ্যাক' সরঞ্জামটি ব্যবহার করতে পারেন:

pgrphack my_command args

অথবা আপনি আবার পার্ল ফিরে যেতে পারেন:

perl -e 'setpgid or die; exec { $ARGV[0] } @ARGV;' my_command args

এখানে কেবলমাত্র সাবধানতা হ'ল প্রক্রিয়া গোষ্ঠীগুলি বাসা বাঁধে না, সুতরাং যদি কিছু প্রক্রিয়া তার নিজস্ব প্রক্রিয়া গোষ্ঠী তৈরি করে, তবে এর উপ-প্রক্রিয়াগুলি আপনার তৈরি করা গোষ্ঠীতে আর থাকবে না।


শিশু প্রক্রিয়াগুলি স্বেচ্ছাসেবী এবং প্রক্রিয়া গ্রুপগুলি নিজেরাই ব্যবহার করতে পারে বা নাও করতে পারে (আমি কিছুই অনুমান করতে পারি না)। তবে আপনার উত্তরটি লিনাক্সে যা অর্জনযোগ্য বলে মনে হচ্ছে তার নিকটে আসে, তাই আমি এটি গ্রহণ করব। ধন্যবাদ।
STenyaK

এটি খুব দরকারী ছিল!
মিশাল গ্যাল্লোভিক

Pstree পাইপগুলিতে থ্রেড আইডিরও অন্তর্ভুক্ত থাকবে, অর্থাত্ একটি id পিড শুরু হওয়া থ্রেডগুলির আইডি।
ম্যাক্সচেলেপজিগ

আপনি একক pstree -lp | grep -Po "(?<=\()\d+(?=\))"
গ্রেপ

7
descendent_pids() {
    pids=$(pgrep -P $1)
    echo $pids
    for pid in $pids; do
        descendent_pids $pid
    done
}

এটা শুধুমাত্র লক্ষ করেন, এই আধুনিক শাঁস কাজ করবে মূল্য হবে ( bash, zsh, fish, এবং এমনকি ksh 99), কিন্তু পারে পুরোনো শেল কাজ নাও, যেমনksh 88
grochmal

@ গ্রোচমাল, একটি ট্র্যাভার্সাল সমাধানের জন্য নীচে আমার উত্তরটি দেখুন যা ksh-88 এ কাজ করে।
ম্যাক্সচলেপজিগ

1

আমি সবচেয়ে সংক্ষিপ্ত সংস্করণটি পেয়েছি যা কমান্ডগুলির সাথে সঠিকভাবে ডিল করে pop3d:

pstree -p $pid | perl -ne 's/\((\d+)\)/print " $1"/ge'

আপনার যদি কমান্ডগুলির মতো অদ্ভুত নাম রয়েছে: এটি ভুলভাবে ডিল করে my(23)prog


1
এটি এমন কোনও কমান্ডের জন্য কাজ করে না যা কিছু থ্রেড চালাচ্ছে (কারণ pstree সেই আইডিগুলিও প্রিন্ট করে)।
ম্যাক্সচলেপজিগ

@ ম্যাক্সচলেপজিগ ffmpegথ্রেড ব্যবহার করে খুব সমস্যাটি লক্ষ্য করেছেন । যদিও, দ্রুত পর্যবেক্ষণ থেকে, মনে হয় যে থ্রেডগুলি কোঁকড়া ধনুর্বন্ধনী ভিতরে তাদের নামের সাথে দেওয়া হয়েছে { },।
জিপসি স্পেলওয়েভার

1

সঠিকতার বিষয়টিও রয়েছে। নির্লজ্জভাবে আউটপুট পার্স pstreeকরা বিভিন্ন কারণে সমস্যাযুক্ত:

  • pstree পিআইডি এবং থ্রেডগুলির আইডিকে প্রদর্শন করে (নামগুলি কোঁকড়া ধনুর্বন্ধনীতে দেখানো হয়)
  • একটি কমান্ডের নামটিতে কোঁকড়ানো ধনুর্বন্ধনী ধনুর্বন্ধনী, বন্ধনীতে সংখ্যা থাকতে পারে যা বিশ্বাসযোগ্য পার্সিংকে অসম্ভব করে তোলে

যদি আপনার পাইথন এবং psutilপ্যাকেজ ইনস্টল করা থাকে তবে আপনি সমস্ত বংশধর প্রক্রিয়াগুলির তালিকা তৈরি করতে এই স্নিপেটটি ব্যবহার করতে পারেন:

pid=2235; python3 -c "import psutil
for c in psutil.Process($pid).children(True):
  print(c.pid)"

(Psutil প্যাকেজটি উদাহরণস্বরূপ tracerফেডোরা / সেন্টস- এ উপলব্ধ কমান্ডের নির্ভরতা হিসাবে ইনস্টল করা আছে ।)

বিকল্পভাবে, আপনি একটি বোর্ন শেলটিতে প্রক্রিয়া গাছের প্রথম প্রান্তের ট্রভারসাল করতে পারেন:

ps=2235; while [ "$ps" ]; do echo $ps; ps=$(echo $ps | xargs -n1 pgrep -P); \
  done | tail -n +2 | tr " " "\n"

পিডের ট্রানজিটিভ-ক্লোজার গণনার জন্য, লেজের অংশটি বাদ দেওয়া যেতে পারে।

নোট করুন যে উপরেরটি পুনরাবৃত্তি ব্যবহার করে না এবং ksh-88 এও চলে।

লিনাক্সে, কেউ pgrepকলটি মুছে ফেলতে এবং পরিবর্তে এর থেকে তথ্যটি পড়তে পারে /proc:

ps=2235; while [ "$ps" ]; do echo $ps ; \
  ps=$(for p in $ps; do cat /proc/$p/task/$p/children; done); done \
  | tr " " "\n"' | tail -n +2

এটি আরও কার্যকর কারণ আমরা প্রতিটি পিআইডি-র জন্য একটি কাঁটাচামচ / এক্সিকিউটিভ সংরক্ষণ করি pgrepএবং প্রতিটি কলটিতে কিছু অতিরিক্ত কাজ করি।


1

এই লিনাক্স সংস্করণটির জন্য কেবলমাত্র / প্রোক এবং পিএস প্রয়োজন। এটি @ ম্যাক্সচ্লেপজিগের দুর্দান্ত উত্তরের শেষ টুকরো থেকে অভিযোজিত । এই সংস্করণটি লুপে একটি উপ-প্রক্রিয়া তৈরির পরিবর্তে সরাসরি শেল থেকে পঠন / প্রোচ করে। এই থ্রেড শিরোনাম অনুরোধ হিসাবে এটি কিছুটা দ্রুত এবং তর্কযোগ্যভাবে কিছুটা মার্জিত।

#!/bin/dash

# Print all descendant pids of process pid $1
# adapted from /unix//a/339071

ps=${1:-1}
while [ "$ps" ]; do
  echo $ps
  unset ps1 ps2
  for p in $ps; do
    read ps2 < /proc/$p/task/$p/children 2>/dev/null
    ps1="$ps1 $ps2"
  done
  ps=$ps1
done | tr " " "\n" | tail -n +2

0

আপনার দু'জনের (মনে হচ্ছে খুব কৃত্রিম) ব্যবহারের ক্ষেত্রে আপনি কেন কিছু দুর্ভাগ্যজনক প্রক্রিয়াটির উপ-প্রক্রিয়াগুলিকে হত্যা করতে চান? একটি প্রক্রিয়া যখন তার বাচ্চাদের বাঁচা বা মারা উচিত তার চেয়ে ভাল আপনি কীভাবে জানবেন? এটি আমার কাছে খারাপ ডিজাইনের মতো মনে হচ্ছে; একটি প্রক্রিয়া নিজের পরে পরিষ্কার করা উচিত।

আপনি যদি সত্যিই আরও ভাল করে জানেন তবে আপনার এই উপ-প্রক্রিয়াগুলি জোর করে নেওয়া উচিত, এবং 'ডিমনাইজড প্রক্রিয়া' অবশ্যই বিশ্বাসযোগ্য নয় fork(2)

আপনার বাচ্চাদের প্রক্রিয়াগুলির তালিকা রাখা বা প্রক্রিয়া গাছের মাধ্যমে খাঁজ কাটা এড়ানো উচিত, যেমন @ গিলিসের পরামর্শ অনুসারে শিশু প্রক্রিয়াগুলি একটি পৃথক প্রক্রিয়া গ্রুপে রেখে by

যাই হোক না কেন, আমি সন্দেহ করি যে আপনার ডেমনাইজড প্রক্রিয়াটি একটি উপ-সাব-সাব-প্রসেসের গভীর গাছের চেয়ে একটি কর্মী থ্রেড পুল (যা প্রয়োজনীয় এটির প্রক্রিয়াটি সহ অবশ্যই মারা যায়) তৈরি করা ভাল, যা কোথাও কোথাও পরিষ্কার করতে হবে clean ।


2
উভয় ব্যবহারের ক্ষেত্রে অবিচ্ছিন্ন একীকরণ / পরীক্ষার পরিবেশে ব্যবহৃত হয়, তাই তাদের শিশু প্রসেস / এসএস-এ থাকা একটি বাগের সম্ভাবনাটি মোকাবেলা করতে হবে। এই বাগটি নিজেকে বা তাদের সন্তানদের সঠিকভাবে বন্ধ করতে অক্ষম হিসাবে নিজেকে প্রকাশ করতে পারে, তাই আমি সবচেয়ে খারাপ অবস্থাতেই সেগুলি বন্ধ করে দিতে পারি তা নিশ্চিত করার জন্য আমার একটি উপায় প্রয়োজন ।
স্টেনিয়াকে

1
সেক্ষেত্রে আমি @ গিলস এবং @ জেন্ডার এর সাথে আছি; প্রক্রিয়া গ্রুপ সেরা উপায়।
ওয়ান্ডসেল্লিগিক

0

এখানে একটি পিজ্রিপ মোড়ক স্ক্রিপ্ট যা আপনাকে পग्रीপ ব্যবহার করতে এবং একই সাথে সমস্ত বংশধরদের পেতে দেয়।

~/bin/pgrep_wrapper:

#!/bin/bash

# the delimiter argument must be the first arg, otherwise it is ignored
delim=$'\n'
if [ "$1" == "-d" ]; then
    delim=$2
    shift 2
fi

pids=
newpids=$(pgrep "$@")
status=$?
if [ $status -ne 0 ]; then
    exit $status
fi

while [ "$pids" != "$newpids" ]; do
    pids=$newpids
    newpids=$( { echo "$pids"; pgrep -P "$(echo -n "$pids" | tr -cs '[:digit:]' ',')"; } | sort -u )
done
if [ "$delim" != $'\n' ]; then
    first=1
    for pid in $pids; do
        if [ $first -ne 1 ]; then
            echo -n "$delim"
        else
            first=0
        fi  
        echo -n "$pid"
    done
else
    echo "$pids"
fi

আপনি যেমন সাধারণ পিগ্রেপ অনুরোধ করেন ঠিক তেমন অনুরোধ করুন যেমন pgrep_recursive -U $USER javaবর্তমান ব্যবহারকারীর কাছ থেকে সমস্ত জাভা প্রক্রিয়া এবং উপ-প্রক্রিয়াগুলি সন্ধান করতে।


1
যেহেতু এই ব্যাশ, আমি একটি বিভেদক সঙ্গে PIDs যোগ দেওয়ার জন্য ব্যবহার করা কোড বোধ সেটিং দিয়ে প্রতিস্থাপিত করা যেতে পারে আছে IFSএবং অ্যারে ব্যবহার ( "${array[*]}। ")
muru
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.