আমি একটি পুরো প্রক্রিয়া গাছ হত্যা করতে চাই। কোনও সাধারণ স্ক্রিপ্টিং ভাষা ব্যবহার করে এটি করার সর্বোত্তম উপায় কী? আমি একটি সহজ সমাধান খুঁজছি।
chronos
বা herodes
কমান্ড ব্যবহার করুন ।
আমি একটি পুরো প্রক্রিয়া গাছ হত্যা করতে চাই। কোনও সাধারণ স্ক্রিপ্টিং ভাষা ব্যবহার করে এটি করার সর্বোত্তম উপায় কী? আমি একটি সহজ সমাধান খুঁজছি।
chronos
বা herodes
কমান্ড ব্যবহার করুন ।
উত্তর:
আপনি যে গাছটিকে হত্যা করতে চান তা একটি একক প্রক্রিয়া গোষ্ঠী কিনা আপনি বলবেন না। (গাছটি সার্ভার স্টার্ট বা শেল কমান্ড লাইন থেকে কাঁটাচামানের ফলাফল হলে এটি প্রায়শই ঘটে থাকে) আপনি GNU ps ব্যবহার করে প্রক্রিয়া গোষ্ঠীগুলি আবিষ্কার করতে পারেন:
ps x -o "%p %r %y %x %c "
এটি যদি কোনও প্রক্রিয়া গোষ্ঠী হয় যা আপনি হত্যা করতে চান, কেবলমাত্র kill(1)
আদেশটি ব্যবহার করুন তবে এটি একটি প্রক্রিয়া নম্বর দেওয়ার পরিবর্তে, গ্রুপ নম্বরটিকে অস্বীকার করুন । উদাহরণস্বরূপ, 5112 গ্রুপে প্রতিটি প্রক্রিয়া হত্যা করার জন্য ব্যবহার করুন kill -TERM -- -5112
।
pgrep
প্রক্রিয়া গ্রুপ আইডি সন্ধানের জন্য একটি সহজ উপায় অফার করতে পারে। উদাহরণস্বরূপ, my-script.sh প্রক্রিয়াকে গ্রুপ, চালানোর হত্যা করতে kill -TERM -$(pgrep -o my-script.sh)
।
ps -o pid --no-headers --ppid $PARENT_PID
ps x -o "%r %p %y %x %c" | sort -nk1,2
প্রসেস গ্রুপ আইডি ( ) ব্যবহার করে একই প্রক্রিয়া গাছের সাথে সম্পর্কিত সমস্ত প্রক্রিয়া হত্যা করুনPGID
kill -- -$PGID
ডিফল্ট সিগন্যাল ব্যবহার করুন ( TERM
= 15)kill -9 -$PGID
সিগন্যাল ব্যবহার করুন KILL
(9)আপনি একই প্রক্রিয়া গাছের যে PGID
কোনও প্রসেস-আইডি ( PID
) থেকে পুনরুদ্ধার করতে পারেন
kill -- -$(ps -o pgid= $PID | grep -o '[0-9]*')
(সংকেত TERM
)kill -9 -$(ps -o pgid= $PID | grep -o '[0-9]*')
(সংকেত KILL
)বিশেষ ধন্যবাদ tanager এবং Speakus উপর অবদানসমূহের জন্য $PID
অবশিষ্ট স্পেস এবং ওএসএক্স সামঞ্জস্য।
kill -9 -"$PGID"
=> KILL
সমস্ত বাচ্চা এবং নাতনীর কাছে 9 ( ) সংকেত প্রেরণ করুন ...PGID=$(ps opgid= "$PID")
=> গাছের যেকোন প্রসেস -আইডি থেকে প্রক্রিয়া-গোষ্ঠী-আইডিটি পুনরুদ্ধার করুন , কেবলমাত্র প্রক্রিয়া-পিতামাতা-আইডি নয় । একটি প্রকরণ হয় যেখানে দ্বারা প্রতিস্থাপিত হতে পারে । কিন্তু:
ps opgid= $PID
ps -o pgid --no-headers $PID
pgid
pgrp
ps
PID
পাঁচ অঙ্কের চেয়ে কম হলে শীর্ষস্থানীয় স্থান সন্নিবেশ করানো হয় এবং টেঞ্জার দ্বারা চিহ্নিত হিসাবে ডানদিকে সংযুক্ত করা হয় । তুমি ব্যবহার করতে পার:PGID=$(ps opgid= "$PID" | tr -d ' ')
ps
ওএসএক্স থেকে সর্বদা শিরোনাম মুদ্রণ করে, তাই স্পাইকাস প্রস্তাব দেয়:PGID="$( ps -o pgid "$PID" | grep [0-9] | tr -d ' ' )"
grep -o [0-9]*
কেবল পরের সংখ্যাগুলি মুদ্রণ করে (ফাঁকা স্থান বা বর্ণমালা শিরোনামগুলি প্রিন্ট করে না)।PGID=$(ps -o pgid= $PID | grep -o [0-9]*)
kill -TERM -"$PGID" # kill -15
kill -INT -"$PGID" # correspond to [CRTL+C] from keyboard
kill -QUIT -"$PGID" # correspond to [CRTL+\] from keyboard
kill -CONT -"$PGID" # restart a stopped process (above signals do not kill it)
sleep 2 # wait terminate process (more time if required)
kill -KILL -"$PGID" # kill -9 if it does not intercept signals (or buggy)
kill
একই গাছের সাথে সম্পর্কিত কোনও প্রক্রিয়া চালিত হয় তখন kill
পুরো গাছ নিধন বন্ধ করার আগে নিজেকে হত্যা করার ঝুঁকি থাকে।> cat run-many-processes.sh
#!/bin/sh
echo "ProcessID=$$ begins ($0)"
./child.sh background &
./child.sh foreground
echo "ProcessID=$$ ends ($0)"
> cat child.sh
#!/bin/sh
echo "ProcessID=$$ begins ($0)"
./grandchild.sh background &
./grandchild.sh foreground
echo "ProcessID=$$ ends ($0)"
> cat grandchild.sh
#!/bin/sh
echo "ProcessID=$$ begins ($0)"
sleep 9999
echo "ProcessID=$$ ends ($0)"
'এবং' ব্যবহার করে পটভূমিতে প্রক্রিয়া ট্রিটি চালান
> ./run-many-processes.sh &
ProcessID=28957 begins (./run-many-processes.sh)
ProcessID=28959 begins (./child.sh)
ProcessID=28958 begins (./child.sh)
ProcessID=28960 begins (./grandchild.sh)
ProcessID=28961 begins (./grandchild.sh)
ProcessID=28962 begins (./grandchild.sh)
ProcessID=28963 begins (./grandchild.sh)
> PID=$! # get the Parent Process ID
> PGID=$(ps opgid= "$PID") # get the Process Group ID
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348 28349 28349 28349 pts/3 28969 Ss 33021 0:00 -bash
28349 28957 28957 28349 pts/3 28969 S 33021 0:00 \_ /bin/sh ./run-many-processes.sh
28957 28958 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./child.sh background
28958 28961 28957 28349 pts/3 28969 S 33021 0:00 | | \_ /bin/sh ./grandchild.sh background
28961 28965 28957 28349 pts/3 28969 S 33021 0:00 | | | \_ sleep 9999
28958 28963 28957 28349 pts/3 28969 S 33021 0:00 | | \_ /bin/sh ./grandchild.sh foreground
28963 28967 28957 28349 pts/3 28969 S 33021 0:00 | | \_ sleep 9999
28957 28959 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./child.sh foreground
28959 28960 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./grandchild.sh background
28960 28964 28957 28349 pts/3 28969 S 33021 0:00 | | \_ sleep 9999
28959 28962 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./grandchild.sh foreground
28962 28966 28957 28349 pts/3 28969 S 33021 0:00 | \_ sleep 9999
28349 28969 28969 28349 pts/3 28969 R+ 33021 0:00 \_ ps fj
কমান্ড pkill -P $PID
নাতি নাতিকে হত্যা করে না:
> pkill -P "$PID"
./run-many-processes.sh: line 4: 28958 Terminated ./child.sh background
./run-many-processes.sh: line 4: 28959 Terminated ./child.sh foreground
ProcessID=28957 ends (./run-many-processes.sh)
[1]+ Done ./run-many-processes.sh
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348 28349 28349 28349 pts/3 28987 Ss 33021 0:00 -bash
28349 28987 28987 28349 pts/3 28987 R+ 33021 0:00 \_ ps fj
1 28963 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh foreground
28963 28967 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
1 28962 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh foreground
28962 28966 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
1 28961 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh background
28961 28965 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
1 28960 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh background
28960 28964 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
কমান্ড kill -- -$PGID
নাতি-নাতনী সহ সমস্ত প্রক্রিয়া হত্যা করে।
> kill -- -"$PGID" # default signal is TERM (kill -15)
> kill -CONT -"$PGID" # awake stopped processes
> kill -KILL -"$PGID" # kill -9 to be sure
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348 28349 28349 28349 pts/3 29039 Ss 33021 0:00 -bash
28349 29039 29039 28349 pts/3 29039 R+ 33021 0:00 \_ ps fj
আমি এই উদাহরণে লক্ষ্য করেছি PID
এবং PGID
সমান ( 28957
)।
এই কারণেই আমি মূলত ভেবেছিলাম kill -- -$PID
যথেষ্ট ছিল। কিন্তু ক্ষেত্রে প্রক্রিয়া মধ্যে একটি ডিম হয় প্রক্রিয়া ID থেকে ভিন্ন গোষ্ঠী ID ।Makefile
আমি মনে করি kill -- -$(ps -o pgid= $PID | grep -o [0-9]*)
কোনও আলাদা গ্রুপ আইডি (অন্য একটি প্রক্রিয়া ট্রি) থেকে কল করার সময় পুরো প্রক্রিয়া গাছটিকে মেরে ফেলার জন্য সেরা সহজ কৌশল ।
kill
নিজের সিগন্যাল পাওয়ার আগে পুরো গাছটিতে সর্বদা সিগন্যাল প্রেরণ করা উচিত। তবে কিছু নির্দিষ্ট পরিস্থিতিতে / বাস্তবায়নে, kill
সিগন্যালটি নিজের কাছে প্রেরণ করতে পারে, বাধা দেওয়া হতে পারে এবং তার পরে তার নিজস্ব সংকেত পেতে পারে। তবে ঝুঁকিটি যথেষ্ট পরিমাণে ন্যূনতম হওয়া উচিত এবং বেশিরভাগ ক্ষেত্রেই তা উপেক্ষা করা যেতে পারে কারণ এর আগে অন্যান্য বাগগুলি হওয়া উচিত। আপনার ক্ষেত্রে কি এই ঝুঁকি উপেক্ষা করা যেতে পারে? তদুপরি অন্যান্য উত্তরগুলির মধ্যে এই সাধারণ বাগ রয়েছে ( kill
প্রক্রিয়া গাছটি মারা যাওয়ার অংশ)। আশা করি এই সহায়তা .. চিয়ার্স;)
man
। অন্যদিকে, আপনি যদি শিশু প্রক্রিয়া থেকে গ্যান্ডচিল্ড প্রক্রিয়াটি মেরে ফেলতে চান তবে kill -- -$pid
কাজ করবে না। সুতরাং এটি জেনেরিক সমাধান নয়।
child.sh
।
pkill -TERM -P 27888
এটি প্যারেন্ট প্রসেস আইডি 27888 থাকা সমস্ত প্রক্রিয়াটিকে হত্যা করবে।
বা আরও শক্তিশালী:
CPIDS=$(pgrep -P 27888); (sleep 33 && kill -KILL $CPIDS &); kill -TERM $CPIDS
যা পরে ৩৩ সেকেন্ডে হত্যার সময়সূচী এবং বিনয়ের সাথে প্রক্রিয়াগুলি বন্ধ করতে বলে।
সমস্ত বংশধরকে সমাপ্ত করার জন্য এই উত্তরটি দেখুন ।
pkill -P
কেবলমাত্র সন্তানের কাছে সিগন্যাল প্রেরণ করে => নাতি নাতনি সিগন্যাল পান না => সুতরাং এটি ব্যাখ্যা করার জন্য আমি আর একটি উত্তর কটাক্ষ করেছি । চিয়ার্স ;-)
pkill -TERM -P ${$}
।
$ time for i in {1..32768}; do ( echo $BASHPID >> pids ); done real 0m18.860s
একটি প্রক্রিয়া গাছ পুনরাবৃত্তভাবে হত্যা করতে, কিলট্রি ব্যবহার করুন ():
#!/bin/bash
killtree() {
local _pid=$1
local _sig=${2:--TERM}
kill -stop ${_pid} # needed to stop quickly forking parent from producing children between child killing and parent killing
for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
killtree ${_child} ${_sig}
done
kill -${_sig} ${_pid}
}
if [ $# -eq 0 -o $# -gt 2 ]; then
echo "Usage: $(basename $0) <pid> [signal]"
exit 1
fi
killtree $@
--
আর্গুমেন্ট ps
সেখানে কাজ করা প্রতিস্থাপন উপর OS X এর জন্য কাজ করে না ps
: দ্বারা কমান্ড ps ax -o "pid= ppid=" | grep -E "${_regex}" | sed -E "s/${_regex}/\1/g
যেখানে _regex
আগে সংজ্ঞায়িত করা হয় for
: লুপlocal _regex="[ ]*([0-9]+)[ ]+${_pid}"
killtree()
নির্ভরযোগ্যতার সাথে কাজ করে তার গ্যারান্টি দেওয়ার জন্য সিগমেন্টের জায়গায় একটি সাইনकिल পাঠানো কি যথেষ্ট ?
ps
সমর্থন না করে তবে তার পরিবর্তে --ppid
কেউ ব্যবহার করতে পারবেনpgrep -P ${_pid}
ব্র্যাডের উত্তরটি হ'ল আমিও সুপারিশ করব, আপনি awk
যদি --ppid
বিকল্পটি ব্যবহার করেন তবে আপনি সম্পূর্ণরূপে তা করতে পারবেন ps
।
for child in $(ps -o pid -ax --ppid $PPID) do ....... done
আপনি যদি জানেন যে পিতামাতার প্রক্রিয়াটির পিডটি পাস করেন তবে এখানে একটি শেল স্ক্রিপ্ট রয়েছে যা কাজ করা উচিত:
for child in $(ps -o pid,ppid -ax | \
awk "{ if ( \$2 == $pid ) { print \$1 }}")
do
echo "Killing child process $child because ppid = $pid"
kill $child
done
আমি এখানে বর্ণিত একটি পদ্ধতির কিছুটা সংশোধিত সংস্করণ ব্যবহার করছি: https://stackoverflow.com/a/5311362/563175
সুতরাং এটির মতো দেখাচ্ছে:
kill `pstree -p 24901 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "`
যেখানে 24901 হল পিতামাতার পিআইডি।
এটি দেখতে বেশ কুৎসিত দেখাচ্ছে তবে এটি পুরোপুরি কার্যকর।
pstree -p 24901 | grep -oP '(?<=\()[0-9]+(?=\))'
-l
করা উচিত pstree
, যাতে দীর্ঘ লাইন কাটা না; এটিকে আরও সহজভাবে পড়া যায় kill `pstree -l -p 24901 |grep "([[:digit:]]*)" -o |tr -d '()'`
( \n
স্পেসে রূপান্তর করার দরকার নেই কারণ এটি ঠিকঠাক কাজ করবে), থেক্স!
জিগাংয়ের উত্তরের পরিবর্তিত সংস্করণ:
#!/usr/bin/env bash
set -eu
killtree() {
local pid
for pid; do
kill -stop $pid
local cpid
for cpid in $(pgrep -P $pid); do
killtree $cpid
done
kill $pid
kill -cont $pid
wait $pid 2>/dev/null || true
done
}
cpids() {
local pid=$1 options=${2:-} space=${3:-}
local cpid
for cpid in $(pgrep -P $pid); do
echo "$space$cpid"
if [[ "${options/a/}" != "$options" ]]; then
cpids $cpid "$options" "$space "
fi
done
}
while true; do sleep 1; done &
cpid=$!
for i in $(seq 1 2); do
cpids $$ a
sleep 1
done
killtree $cpid
echo ---
cpids $$ a
wait $pid
কেবল প্রক্রিয়াকরণেই শুরু করতে পারেন , সমস্ত প্রেজেস নয়, সুতরাং এটি সাধারণ সমাধান নয়
wait
দমন করবে Terminated
।
আমি মন্তব্য করতে পারি না (পর্যাপ্ত খ্যাতি নেই), সুতরাং এটি সত্যিই উত্তর না হলেও আমি একটি নতুন উত্তর যুক্ত করতে বাধ্য হচ্ছি ।
ফেব্রুয়ারী 28. উপর @olibre কর্তৃক প্রদত্ত আউটপুট অন্যথায় খুব সুন্দর এবং পুঙ্খানুপুঙ্খ জবাব দিয়ে একটি সামান্য সমস্যা আছে ps opgid= $PID
খাটো চেয়ে পাঁচটি সংখ্যা একটি PID জন্য নেতৃস্থানীয় খালি জায়গা থাকা কারণ ps
কলাম (ঠিক আছে সারিবদ্ধ নম্বর) justifying হয়। পুরো কমান্ড লাইনের মধ্যে, এর ফলাফলটি নেতিবাচক চিহ্নের পরে স্থান (গুলি) এবং গ্রুপ পিআইডি অনুসরণ করে। সহজ সমাধানটি ফাঁকাগুলি সরিয়ে আনার জন্য পাইপ ps
দেওয়া tr
:
kill -- -$( ps opgid= $PID | tr -d ' ' )
নরম্যান রামসির উত্তরে যুক্ত করার জন্য, আপনি যদি একটি প্রক্রিয়া গ্রুপ তৈরি করতে চান তবে সেটসাইডের দিকে তাকানো উপযুক্ত হতে পারে।
http://pubs.opengroup.org/onlinepubs/009695399/functions/setsid.html
কলিং প্রক্রিয়া কোনও প্রক্রিয়া গ্রুপ লিডার না হলে সেটসাইড () ফাংশনটি একটি নতুন অধিবেশন তৈরি করবে। প্রত্যাবর্তনের পরে কলিং প্রক্রিয়া এই নতুন অধিবেশনটির সেশন লিডার হবে, একটি নতুন প্রক্রিয়া গ্রুপের প্রক্রিয়া গ্রুপের নেতা হবে এবং এর কোনও নিয়ন্ত্রণকারী টার্মিনাল থাকবে না। কলিং প্রক্রিয়াটির প্রসেস গ্রুপ আইডি কলিং প্রক্রিয়াটির প্রসেস আইডির সমান সেট করা হবে। কলিং প্রক্রিয়াটি নতুন প্রক্রিয়া গ্রুপের একমাত্র প্রক্রিয়া এবং নতুন সেশনে একমাত্র প্রক্রিয়া হবে।
যার অর্থ আমি গ্রহণ করি যে আপনি প্রারম্ভিক প্রক্রিয়া থেকে একটি গোষ্ঠী তৈরি করতে পারেন। আমি পিএইচপি ব্যবহার করে এটি শুরু করার পরে একটি সম্পূর্ণ প্রক্রিয়া গাছকে মেরে ফেলতে সক্ষম হতে।
এটি একটি খারাপ ধারণা হতে পারে। আমি মন্তব্য করতে আগ্রহী হতে হবে।
Ysth এর মন্তব্যে অনুপ্রাণিত
kill -- -PGID
এটিকে একটি প্রক্রিয়া নম্বর দেওয়ার পরিবর্তে, এটি গ্রুপ নম্বরটিকে অস্বীকার করুন। প্রায় কোনও কমান্ডের সাথে যথারীতি, আপনি যদি একটি সাধারণ যুক্তি চান যা
-
একটি স্যুইচ হিসাবে ব্যাখ্যা না করার জন্য শুরু হয় তবে এর আগে এটি দিয়ে দিন--
নিম্নলিখিত শেল ফাংশন অন্যান্য উত্তরগুলির সাথে অনেকগুলি অনুরূপ, তবে এটি বাহ্যিক নির্ভরতা ছাড়াই লিনাক্স এবং বিএসডি (ওএস এক্স, ইত্যাদি) উভয় ক্ষেত্রেই কাজ করে pgrep
:
killtree() {
local parent=$1 child
for child in $(ps -o ppid= -o pid= | awk "\$1==$parent {print \$2}"); do
killtree $child
done
kill $parent
}
$child
একই ফাংশনের সীমাবদ্ধ করে যাতে একই নামের সাথে অন্যান্য (অ-স্থানীয়) ভেরিয়েবলগুলিকে বিরক্ত না করে এবং ফাংশন শেষ হওয়ার পরে স্থানীয় ভেরিয়েবলের মান পরিষ্কার হয়ে যায় তা নিশ্চিত করতে।
সিউটিল ব্যবহার করে অজগর দিয়ে এটি করা খুব সহজ । কেবল পিপ দিয়ে psutil ইনস্টল করুন এবং তারপরে আপনার কাছে প্রক্রিয়া ম্যানিপুলেশন সরঞ্জামগুলির একটি সম্পূর্ণ স্যুট রয়েছে:
def killChildren(pid):
parent = psutil.Process(pid)
for child in parent.get_children(True):
if child.is_running():
child.terminate()
আপনি যদি নামে কোনও প্রক্রিয়াটি হত্যা করতে চান:
killall -9 -g someprocessname
অথবা
pgrep someprocessname | xargs pkill -9 -g
এটি আমার বাশ স্ক্রিপ্ট ব্যবহার করে সমস্ত শিশু প্রক্রিয়া হত্যার সংস্করণ। এটি পুনরাবৃত্তি ব্যবহার করে না এবং pgrep কমান্ডের উপর নির্ভর করে।
ব্যবহার
killtree.sh PID SIGNAL
কিলট্রি.এস এর সামগ্রীসমূহ
#!/bin/bash
PID=$1
if [ -z $PID ];
then
echo "No pid specified"
fi
PPLIST=$PID
CHILD_LIST=`pgrep -P $PPLIST -d,`
while [ ! -z "$CHILD_LIST" ]
do
PPLIST="$PPLIST,$CHILD_LIST"
CHILD_LIST=`pgrep -P $CHILD_LIST -d,`
done
SIGNAL=$2
if [ -z $SIGNAL ]
then
SIGNAL="TERM"
fi
#do substring from comma to space
kill -$SIGNAL ${PPLIST//,/ }
এখানে @ জিগাংয়ের উত্তরের বিভিন্নতা যা এডাব্লুকে দিয়ে না করে কেবল বাশের নেটিভ পার্সিং সম্ভাবনার উপর নির্ভর করে:
function killtree {
kill -STOP "$1"
ps -e -o pid= -o ppid= | while read -r pid ppid
do
[[ $ppid = $1 ]] || continue
killtree "$pid" || true # Skip over failures
done
kill -CONT "$1"
kill -TERM "$1"
}
এটি ম্যাক এবং লিনাক্স উভয় ক্ষেত্রেই দুর্দান্ত কাজ করেছে বলে মনে হচ্ছে। এমন পরিস্থিতিতে যেখানে আপনি প্রক্রিয়া গোষ্ঠী পরিচালনা করতে সক্ষম হওয়ার উপর নির্ভর করতে পারবেন না - যেমন একাধিক পরিবেশে তৈরি করা আবশ্যক সফ্টওয়্যারটির টুকরো পরীক্ষা করার জন্য স্ক্রিপ্টগুলি লেখার সময় - এই গাছ-চলার কৌশলটি অবশ্যই সহায়ক।
আপনার জ্ঞানের জন্য ধন্যবাদ, ভাবেন। আমার স্ক্রিপ্টটি কিছু শিশু প্রক্রিয়াগুলি প্রস্থান করার সময় ছেড়ে চলেছিল এবং অবহেলার পরামর্শটি জিনিসগুলিকে আরও সহজ করে তুলেছিল । প্রয়োজনে অন্যান্য স্ক্রিপ্টগুলিতে ব্যবহার করার জন্য আমি এই ফাংশনটি লিখেছিলাম:
# kill my group's subprocesses: killGroup
# kill also myself: killGroup -x
# kill another group's subprocesses: killGroup N
# kill that group all: killGroup -x N
# N: PID of the main process (= process group ID).
function killGroup () {
local prid mainpid
case $1 in
-x) [ -n "$2" ] && kill -9 -$2 || kill -9 -$$ ;;
"") mainpid=$$ ;;
*) mainpid=$1 ;;
esac
prid=$(ps ax -o pid,pgid | grep $mainpid)
prid=${prid//$mainpid/}
kill -9 $prid 2>/dev/null
return
}
চিয়ার্স।
বাচ্চাদের আগে পিতামাতাকে হত্যা করা ভাল is অন্যথায় পিতা বা মাতা সম্ভবত নিজেকে হত্যার আগে নতুন বাচ্চাদের জন্ম দিতে পারে। এগুলি হত্যার হাত থেকে বাঁচবে।
আমার পিএস এর সংস্করণ উপরের থেকে পৃথক; সম্ভবত খুব পুরানো, তাই অদ্ভুত গ্রেপিং ...
শেল ফাংশনের পরিবর্তে শেল স্ক্রিপ্ট ব্যবহার করার অনেক সুবিধা রয়েছে ...
তবে এটি মূলত জিগাংসের ধারণা
#!/bin/bash
if test $# -lt 1 ; then
echo >&2 "usage: kiltree pid (sig)"
fi ;
_pid=$1
_sig=${2:-TERM}
_children=$(ps j | grep "^[ ]*${_pid} " | cut -c 7-11) ;
echo >&2 kill -${_sig} ${_pid}
kill -${_sig} ${_pid}
for _child in ${_children}; do
killtree ${_child} ${_sig}
done
নিম্নলিখিতটি ফ্রিবিএসডি, লিনাক্স এবং ম্যাকোস এক্স-তে পরীক্ষা করা হয়েছে এবং কেবল পিগ্রিপ এবং কিলের উপর নির্ভর করে (পিএস -o সংস্করণগুলি BSD এর অধীনে কাজ করে না)। প্রথম যুক্তি হ'ল প্যারেন্ট পিড যা বাচ্চাদের শেষ করতে হবে। দ্বিতীয় আর্গুমেন্ট একটি বুলিয়ান যা প্যারেন্ট পিডটিও বন্ধ করতে হবে কিনা তা নির্ধারণ করতে।
KillChilds() {
local pid="${1}"
local self="${2:-false}"
if children="$(pgrep -P "$pid")"; then
for child in $children; do
KillChilds "$child" true
done
fi
if [ "$self" == true ]; then
kill -s SIGTERM "$pid" || (sleep 10 && kill -9 "$pid" &)
fi
}
KillChilds $$ > /dev/null 2>&1
এটি শেল স্ক্রিপ্টের মধ্যে যে কোনও শিশু / নাতি-নাতনি প্রক্রিয়ায় সিগনটার পাঠাবে এবং যদি সাইনটার্ম সফল না হয় তবে এটি 10 সেকেন্ড অপেক্ষা করবে এবং তারপরে হত্যা পাঠাবে।
পূর্বের উত্তর:
নিম্নলিখিতগুলিও কাজ করে তবে শেলটি নিজেই BSD এ হত্যা করবে।
KillSubTree() {
local parent="${1}"
for child in $(ps -o pid=$parent); do
if [ $$ -ne $child ]; then (kill -s SIGTERM $child || (sleep 10 && kill -9 $child & )) > /dev/null 2>&1 ; fi
done
}
# Example lanch from within script
KillSubTree $$ > /dev/null 2>&1
আমি আরও আগে জিগাং, জিউরি এবং সলডসেকের সমাধানটি বিকাশ করি:
#!/bin/bash
if test $# -lt 1 ; then
echo >&2 "usage: kiltree pid (sig)"
exit 1 ;
fi ;
_pid=$1
_sig=${2:-TERM}
# echo >&2 "killtree($_pid) mypid = $$"
# ps axwwf | grep -6 "^[ ]*$_pid " >&2 ;
function _killtree () {
local _children
local _child
local _success
if test $1 -eq $2 ; then # this is killtree - don't commit suicide!
echo >&2 "killtree can´t kill it´s own branch - some processes will survive." ;
return 1 ;
fi ;
# this avoids that children are spawned or disappear.
kill -SIGSTOP $2 ;
_children=$(ps -o pid --no-headers --ppid $2) ;
_success=0
for _child in ${_children}; do
_killtree $1 ${_child} $3 ;
_success=$(($_success+$?)) ;
done ;
if test $_success -eq 0 ; then
kill -$3 $2
fi ;
# when a stopped process is killed, it will linger in the system until it is continued
kill -SIGCONT $2
test $_success -eq 0 ;
return $?
}
_killtree $$ $_pid $_sig
এই সংস্করণটি তার পূর্বসূরীদের হত্যা এড়াতে পারবে - যা পূর্ববর্তী সমাধানগুলিতে শিশু প্রক্রিয়াগুলির বন্যার কারণ হয়।
বাচ্চাদের তালিকা নির্ধারণের আগে প্রক্রিয়াগুলি যথাযথভাবে বন্ধ হয়ে যায়, যাতে কোনও নতুন শিশু তৈরি না হয় এবং অদৃশ্য হয়।
নিহত হওয়ার পরে, বন্ধ হওয়া কাজগুলি সিস্টেম থেকে অদৃশ্য হয়ে যেতে হবে।
পুরানো প্রশ্ন, আমি জানি, তবে সমস্ত প্রতিক্রিয়া পিএস কল করতে থাকে বলে মনে হয় যা আমি পছন্দ করি না।
এই জাল-ভিত্তিক সমাধানটির পুনরাবৃত্তি প্রয়োজন হয় না এবং কেবল একবার পিএস কল করে।
awk 'BEGIN {
p=1390
while ("ps -o ppid,pid"|getline) a[$1]=a[$1]" "$2
o=1
while (o==1) {
o=0
split(p, q, " ")
for (i in q) if (a[q[i]]!="") {
p=p""a[q[i]]
o=1
a[q[i]]=""
}
}
system("kill -TERM "p)
}'
বা একটি একক লাইনে:
awk 'BEGIN {p=1390;while ("ps -o ppid,pid"|getline) a[$1]=a[$1]" "$2;o=1;while (o==1) {o=0;split(p, q, " ");for (i in q) {if (a[q[i]]!="") {p=p""a[q[i]];o=1;a[q[i]]=""}}}system("kill -TERM "p)}'
মূলত ধারণাটি হ'ল আমরা পিতামাতার একটি অ্যারে (ক) তৈরি করি: সন্তানের এন্ট্রিগুলি, তারপরে অ্যারেটি মিলিয়ে আমাদের মেলানো পিতা-মাতার জন্য বাচ্চাদের সন্ধান করে, আমাদের পিতামাতার তালিকায় যুক্ত হয় (পি) আমরা যাই।
আপনি যদি শীর্ষ-স্তরের প্রক্রিয়াটি হত্যা করতে না চান, তবে করছেন
sub(/[0-9]*/, "", p)
সিস্টেম () লাইনটি কিল সেট থেকে এটি সরিয়ে দেবে তার ঠিক আগে।
মনে রাখবেন যে এখানে একটি দৌড়ের শর্ত রয়েছে তবে এটি সমাধানের সমস্ত ক্ষেত্রে সত্য (যতদূর আমি দেখতে পাচ্ছি)। এটি আমার যা প্রয়োজন ছিল তা করে কারণ আমার যে স্ক্রিপ্টটির জন্য এটির দরকার ছিল তা প্রচুর স্বল্পজীবী বাচ্চাদের তৈরি করে না।
পাঠকের জন্য এটি একটি 2-পাস লুপ তৈরির অনুশীলন হবে: প্রথম পাসের পরে, পি তালিকার সমস্ত প্রসেসে SIGSTOP প্রেরণ করুন, আবার পিএস চালানোর জন্য লুপ করুন এবং দ্বিতীয় পাসের পরে সিগনটারম প্রেরণ করুন, তারপরে সিগনকন্ট করুন। আপনি যদি ভাল পরিণতি সম্পর্কে চিন্তা না করেন তবে দ্বিতীয় পাসটি কেবল সিক্কিল হতে পারে, আমি মনে করি।
আপনি যে জিনিসটিকে হত্যা করতে চান তার পিডটি যদি আপনি জানেন তবে আপনি সাধারণত সেশন আইডি এবং একই সেশনের সমস্ত কিছু থেকে যেতে পারেন। আমি ডাবল চেক করতাম, তবে আমি এটিকে স্ক্রিপ্টগুলির জন্য লুপগুলিতে আরসিএনসি শুরু করার জন্য ব্যবহার করেছি যা আমি মরতে চাই এবং অন্যটি (লুপের কারণে) শুরু করতাম না কারণ যদি আমি কেবল আরএসসিএনসি করতাম।
kill $(ps -o pid= -s $(ps -o sess --no-heading --pid 21709))
আপনি যদি পিড না জানেন তবে আপনি আরও বাসা বাঁধতে পারেন
kill $(ps -o pid= -s $(ps -o sess --no-heading --pid $(pgrep rsync )))
ps -o pid= --ppid $PPID | xargs kill -9
kill -9
সত্যিই না ।
kill -15
সাহায্য করবে না।
Sh এ জবস কমান্ড ব্যাকগ্রাউন্ড প্রক্রিয়াগুলি তালিকাভুক্ত করবে। কিছু ক্ষেত্রে প্রথমে সর্বাধিক নতুন প্রক্রিয়াটি মেরে ফেলা ভাল, উদাহরণস্বরূপ পুরানোটি একটি ভাগ করা সকেট তৈরি করেছে। এই ক্ষেত্রে পিআইডিগুলি বিপরীত ক্রমে সাজান। কখনও কখনও আপনি চাকরীর জন্য থেমে যাওয়ার আগে ডিস্ক বা স্টাফের মতো কিছু লেখার জন্য মুহুর্তের অপেক্ষা করতে চান।
আর না হলে মারবেন না!
for SIGNAL in TERM KILL; do
for CHILD in $(jobs -s|sort -r); do
kill -s $SIGNAL $CHILD
sleep $MOMENT
done
done
শেল স্ক্রিপ্টে শিশু প্রক্রিয়া হত্যা:
অনেক সময় আমাদের এমন শিশু প্রক্রিয়াটি মেরে ফেলতে হবে যা কোনও কারণে ফাঁসি দেওয়া বা কোনও কারণে অবরুদ্ধ। যেমন। এফটিপি সংযোগ সমস্যা।
দুটি পন্থা আছে,
1) প্রতিটি সন্তানের জন্য পৃথক নতুন পিতা বা মাতা তৈরি করা যা একবারের সময়সীমা শেষ হওয়ার পরে শিশু প্রক্রিয়াটি নিরীক্ষণ ও হত্যা করে।
টেস্ট.শ তৈরি করুন নিম্নরূপ,
#!/bin/bash
declare -a CMDs=("AAA" "BBB" "CCC" "DDD")
for CMD in ${CMDs[*]}; do
(sleep 10 & PID=$!; echo "Started $CMD => $PID"; sleep 5; echo "Killing $CMD => $PID"; kill $PID; echo "$CMD Completed.") &
done
exit;
এবং নীচের কমান্ড ব্যবহার করে অন্যান্য টার্মিনালে 'টেস্ট' নামে নাম রয়েছে এমন প্রসেসগুলি দেখুন।
watch -n1 'ps x -o "%p %r %c" | grep "test" '
উপরে স্ক্রিপ্ট 4 টি নতুন শিশু প্রক্রিয়া এবং তাদের পিতামাতাকে তৈরি করবে। প্রতিটি শিশু প্রক্রিয়া 10 সেকেন্ডে চলবে। তবে একবার 5 সেকেন্ডে পৌঁছানোর সময় শেষ হওয়ার পরে, তাদের নিজ নিজ পিতামাতার প্রক্রিয়াগুলি সেই শিশুদের মেরে ফেলবে। সুতরাং শিশু মৃত্যুদণ্ড কার্যকর করতে সক্ষম হবে না (10 সেক্সি)। অন্য আচরণ দেখতে এই সময়গুলির চারপাশে খেলুন (10 এবং 5 স্যুইচ করুন)। সেক্ষেত্রে 10 সিসির সময়সীমা শেষ হওয়ার আগে শিশু 5 সেকেন্ডে মৃত্যুদন্ড কার্যকর করবে।
২) বর্তমান পিতামাতাকে সময়সীমা শেষ হওয়ার পরে শিশু প্রক্রিয়াটি পর্যবেক্ষণ করতে এবং হত্যা করতে দিন। এটি প্রতিটি সন্তানের নিরীক্ষণের জন্য পৃথক পিতামাতার তৈরি করবে না। এছাড়াও আপনি একই পিতামাতার মধ্যে সমস্ত শিশু প্রক্রিয়া সঠিকভাবে পরিচালনা করতে পারেন।
টেস্ট.শ তৈরি করুন নিম্নরূপ,
#!/bin/bash
declare -A CPIDs;
declare -a CMDs=("AAA" "BBB" "CCC" "DDD")
CMD_TIME=15;
for CMD in ${CMDs[*]}; do
(echo "Started..$CMD"; sleep $CMD_TIME; echo "$CMD Done";) &
CPIDs[$!]="$RN";
sleep 1;
done
GPID=$(ps -o pgid= $$);
CNT_TIME_OUT=10;
CNT=0;
while (true); do
declare -A TMP_CPIDs;
for PID in "${!CPIDs[@]}"; do
echo "Checking "${CPIDs[$PID]}"=>"$PID;
if ps -p $PID > /dev/null ; then
echo "-->"${CPIDs[$PID]}"=>"$PID" is running..";
TMP_CPIDs[$PID]=${CPIDs[$PID]};
else
echo "-->"${CPIDs[$PID]}"=>"$PID" is completed.";
fi
done
if [ ${#TMP_CPIDs[@]} == 0 ]; then
echo "All commands completed.";
break;
else
unset CPIDs;
declare -A CPIDs;
for PID in "${!TMP_CPIDs[@]}"; do
CPIDs[$PID]=${TMP_CPIDs[$PID]};
done
unset TMP_CPIDs;
if [ $CNT -gt $CNT_TIME_OUT ]; then
echo ${CPIDs[@]}"PIDs not reponding. Timeout reached $CNT sec. killing all childern with GPID $GPID..";
kill -- -$GPID;
fi
fi
CNT=$((CNT+1));
echo "waiting since $b secs..";
sleep 1;
done
exit;
এবং নীচের কমান্ড ব্যবহার করে অন্যান্য টার্মিনালে 'টেস্ট' নামে নাম রয়েছে এমন প্রসেসগুলি দেখুন।
watch -n1 'ps x -o "%p %r %c" | grep "test" '
উপরে স্ক্রিপ্ট 4 টি নতুন শিশু প্রক্রিয়া তৈরি করবে। আমরা সমস্ত শিশু প্রক্রিয়াটির পিডগুলি সংরক্ষণ করছি এবং তারা তাদের মৃত্যুদণ্ড কার্যকর হয়েছে কিনা তা এখনও চালাচ্ছে কিনা তা পরীক্ষা করার জন্য তাদের উপর লুপিং করছি। শিশু প্রক্রিয়া সিএমডি_টাইম সময় পর্যন্ত কার্যকর হবে। তবে যদি CNT_TIME_OUT সময়সীমা পৌঁছে যায় তবে সমস্ত শিশু পিতামাতার প্রক্রিয়াতে মারা যাবে। আচরণ দেখার জন্য আপনি সময় পরিবর্তন করতে এবং স্ক্রিপ্টের সাথে চারপাশে খেলতে পারেন। এই পদ্ধতির একটি অপূর্ণতা হ'ল, এটি সমস্ত শিশু গাছ হত্যার জন্য গ্রুপ আইডি ব্যবহার করছে। তবে পিতামাতা প্রক্রিয়া নিজেই একই গোষ্ঠীর অন্তর্ভুক্ত তাই এটি খুনও হবে।
আপনি যদি পিতামাতাকে হত্যা করতে না চান তবে আপনাকে অন্য গোষ্ঠী আইডিটিকে প্যারেন্ট প্রসেসে নির্ধারণ করতে হবে need
আরো বিস্তারিত এখানে পাওয়া যাবে,
এই স্ক্রিপ্টটিও কাজ করে:
#/bin/sh
while true
do
echo "Enter parent process id [type quit for exit]"
read ppid
if [ $ppid -eq "quit" -o $ppid -eq "QUIT" ];then
exit 0
fi
for i in `ps -ef| awk '$3 == '$ppid' { print $2 }'`
do
echo killing $i
kill $i
done
done
আমি জানি যে এটি পুরানো, তবে এটিই আমার পক্ষে আরও ভাল সমাধান:
killtree() {
for p in $(pstree -p $1 | grep -o "([[:digit:]]*)" |grep -o "[[:digit:]]*" | tac);do
echo Terminating: $p
kill $p
done
}