2009-12-15 14 views
277

मैं अपनी शैल स्क्रिप्ट से पृष्ठभूमि प्रक्रिया शुरू करता हूं, और जब मैं अपनी स्क्रिप्ट समाप्त करता हूं तो मैं इस प्रक्रिया को मारना चाहता हूं।पृष्ठभूमि प्रक्रिया के पीआईडी ​​कैसे प्राप्त करें?

इस प्रक्रिया के पीआईडी ​​को मेरी खोल स्क्रिप्ट से कैसे प्राप्त करें? जहां तक ​​मैं परिवर्तनीय $! देख सकता हूं वर्तमान स्क्रिप्ट का पीआईडी, पृष्ठभूमि प्रक्रिया नहीं है।

+5

$! सही है। क्या आप वाकई बीजी में स्क्रिप्ट शुरू कर रहे हैं? नमूना कृपया – pixelbeat

+4

हाँ $! सही है। मैं गलत था। –

+8

$$ में वर्तमान स्क्रिप्ट पीआईडी ​​है। – HUB

उत्तर

398

आप पृष्ठभूमि की पीआईडी ​​को बचाने की जरूरत समय में घ प्रक्रिया आप इसे प्रारंभ:

foo & 
FOO_PID=$! 
# do other stuff 
kill $FOO_PID 

आप काम पर नियंत्रण उपयोग नहीं कर सकते क्योंकि यह है कि एक इंटरैक्टिव सुविधा है और एक को नियंत्रित करने के लिए टर्मिनल से बंधा। एक स्क्रिप्ट के लिए एक टर्मिनल संलग्न नहीं होगा, इसलिए नौकरी नियंत्रण आवश्यक रूप से उपलब्ध नहीं होगा।

+11

$ के बाद से! अंतिम पृष्ठभूमि प्रक्रिया के पिड देता है। क्या यह संभव है कि कुछ 'foo' और '$!' के बीच शुरू होता है, और हमें 'foo' के बजाय कुछ चीज़ मिलती है? – WiSaGaN

+29

@WiSaGaN: नहीं। उन पंक्तियों के बीच कुछ भी नहीं है। सिस्टम पर कोई अन्य गतिविधि इस पर असर नहीं पड़ेगी। $! आखिरी पृष्ठभूमि प्रक्रिया के पीआईडी ​​में विस्तार होगा _in कि shell_। – camh

+6

... जो आपको 'hoo' एकाधिक पाइप किए गए आदेशों के साथ होता है (उदाहरण के लिए 'tail -f somefile.txt | grep someext')। ऐसे मामलों में, यदि आप यही चाहते थे तो आपको पूंछ कमांड की बजाय '$!' से grep कमांड का पीआईडी ​​मिलेगा। आपको 'जॉब्स' या 'ps' या इस उदाहरण में पसंद का उपयोग करने की आवश्यकता होगी। –

96

आप एक विशेष jobL

^Z 
[1]+ Stopped     guard 

my_mac:workspace r$ jobs -l 
[1]+ 46841 Suspended: 18   guard 

को पाने के लिए इस मामले में jobs -l आदेश का उपयोग कर सकते हैं, 46,841 पीआईडी ​​है।

help jobs से

:

-l रिपोर्ट प्रक्रिया समूह आईडी और नौकरियों की कार्यशील निर्देशिका।

jobs -p एक और विकल्प है जो केवल पीआईडी ​​दिखाता है।

+0

इसे खोल स्क्रिप्ट में उपयोग करने के लिए, आपको आउटपुट को संसाधित करना होगा। – Phil

+6

@ फिल केवल पिड्स सूचीबद्ध करने के लिए: jobs -p। किसी निश्चित नौकरी की पिड सूचीबद्ध करने के लिए: jobs -p% 3। आउटपुट को संसाधित करने की कोई ज़रूरत नहीं है। –

+0

@Erik विभिन्न कमांड/तर्कों के साथ आप मेरी टिप्पणी का संदर्भ बदलते हैं। अतिरिक्त तर्क के बिना आउटपुट को प्रसंस्करण की आवश्यकता है। उत्तर में सुधार का सुझाव दें! – Phil

33
  • $$ वर्तमान स्क्रिप्ट के पीआईडी ​​
  • $! पिछले पृष्ठभूमि प्रक्रिया

यहाँ की पीआईडी ​​है एक बैश सत्र (%1 पृष्ठभूमि प्रक्रिया की क्रमसूचक संख्या को संदर्भित करता है से एक नमूना प्रतिलिपि के रूप में देखा है jobs से):

$ echo $$ 
3748 

$ sleep 100 & 
[1] 192 

$ echo $! 
192 

$ kill %1 

[1]+ Terminated    sleep 100 
+0

पर 'जॉब्स-एल' के रूप में वही लौटाया, '% 1' गूंज मेरे उबंटू पर पृष्ठभूमि प्रक्रिया वापस नहीं करता है जबकि' echo $! ' – Timo

2

तुम भी pstree उपयोग करने में सक्षम हो सकता है:

pstree -p user 

यह आमतौर पर "उपयोगकर्ता" के लिए सभी प्रक्रियाओं का एक पाठ प्रतिनिधित्व करता है और -p विकल्प प्रक्रिया आईडी देता है। जहां तक ​​मैं समझता हूं, प्रक्रियाओं को वर्तमान खोल के स्वामित्व में रखने पर निर्भर नहीं है। यह कांटे भी दिखाता है।

+1

शैल स्क्रिप्ट में इसका उपयोग करने के लिए, आपको भारी प्रक्रिया करना होगा उत्पादन। – Phil

3

यह वही है जो मैंने किया है। इसे देखें, उम्मीद है कि यह मदद कर सकता है। निश्चित रूप से उचित अनुमति के साथ ./bgkill.sh

[email protected] [P]:~# ./bgkill.sh 
PID=23757 
dPidLst= 23758 23759 
UNO 
DOS 
UID  PID PPID C STIME TTY   TIME CMD 
root  3937 3935 0 11:07 pts/5 00:00:00 -bash 
root  23757 3937 0 11:55 pts/5 00:00:00 /bin/bash ./bgkill.sh 
root  23758 23757 0 11:55 pts/5 00:00:00 tail -f UNO.txt 
root  23759 23757 0 11:55 pts/5 00:00:00 tail -f DOS.txt 
root  23760 23757 0 11:55 pts/5 00:00:00 ps -f 
killing 23758. Process is still there. 
23758 pts/5 00:00:00 tail 
./bgkill.sh: line 24: 23758 Terminated    tail -f UNO.txt 
Just ran 'ps' command, 23758 must not show again. 
killing 23759. Process is still there. 
23759 pts/5 00:00:00 tail 
./bgkill.sh: line 24: 23759 Terminated    tail -f DOS.txt 
Just ran 'ps' command, 23759 must not show again. 
[email protected] [P]:~# ps -f 
UID  PID PPID C STIME TTY   TIME CMD 
root  3937 3935 0 11:07 pts/5 00:00:00 -bash 
root  24200 3937 0 11:56 pts/5 00:00:00 ps -f 
1

pgrep आप एक माता पिता की प्रक्रिया के बच्चे PIDs के सभी प्राप्त कर सकते हैं:

#!/bin/bash 
# 
# So something to show. 
echo "UNO" > UNO.txt 
echo "DOS" > DOS.txt 
# 
# Initialize Pid List 
dPidLst="" 
# 
# Generate background processes 
tail -f UNO.txt& 
dPidLst="$dPidLst $!" 
tail -f DOS.txt& 
dPidLst="$dPidLst $!" 
# 
# Report process IDs 
echo PID=$$ 
echo dPidLst=$dPidLst 
# 
# Show process on current shell 
ps -f 
# 
# Start killing background processes from list 
for dPid in $dPidLst 
do 
     echo killing $dPid. Process is still there. 
     ps | grep $dPid 
     kill $dPid 
     ps | grep $dPid 
     echo Just ran "'"ps"'" command, $dPid must not show again. 
done 

तो बस के रूप में यह चलाते हैं। जैसा कि पहले उल्लेख किया गया है $$ वर्तमान स्क्रिप्ट पीआईडी ​​है।

trap 'kill $(pgrep -P $$ | tr "\n" " ")' SIGINT SIGTERM EXIT 
+0

क्या यह बहुत मार नहीं सकता? – Phil

+0

हां, यह प्रश्न कभी भी उल्लेख नहीं किया गया है कि बाहर निकलने पर _some_ पृष्ठभूमि बच्चों को जीवित रखना। –

+0

'जाल' pkill -P $$ 'सिगिंग सिगरेट एक्स्टिट' आसान दिखता है, लेकिन मैंने इसका परीक्षण नहीं किया। – petre

19

एक भी सरल तरीके से एक bash स्क्रिप्ट के सभी बच्चे प्रक्रिया को मारने के लिए:

pkill -P $$ 

-P ध्वज तो, अगर आप एक स्क्रिप्ट है जो अपने आप के बाद को साफ करना चाहते हैं, इस चाल करना चाहिए pkill और pgrep के साथ उसी तरह काम करता है - यह बाल प्रक्रियाओं को प्राप्त करता है, केवल pkill के साथ बच्चे की प्रक्रियाओं को मार दिया जाता है और pgrep बच्चे पीआईडी ​​stdout पर मुद्रित होते हैं।

+0

ग्रेट उत्तर! धन्यवाद :) –

+0

आपका स्वागत है :) –

+0

बहुत सुविधाजनक! यह सुनिश्चित करने का सबसे अच्छा तरीका है कि आप पृष्ठभूमि पर खुले प्रक्रियाओं को न छोड़ें। – lepe

संबंधित मुद्दे