प्रक्रिया आईडी (PID) मौजूद है या नहीं, इसकी जांच कैसे करें


184

बैश स्क्रिप्ट में, मैं निम्नलिखित करना चाहता हूं (छद्म कोड में):

if [ a process exists with $PID ]; then

    kill $PID 

fi

सशर्त कथन के लिए उपयुक्त अभिव्यक्ति क्या है?

जवाबों:


182

एक प्रक्रिया के अस्तित्व की जांच करने के लिए, का उपयोग करें

kill -0 $pid

लेकिन जैसा कि @unwind ने कहा, यदि आप इसे वैसे भी मारने जा रहे हैं, तो बस

kill $pid

या आपके पास एक दौड़ की स्थिति होगी।

यदि आप killबाहर निकलने के कोड के आधार पर कुछ के टेक्स्ट आउटपुट को अनदेखा करना चाहते हैं , तो आप कर सकते हैं

if ! kill $pid > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $pid" >&2
fi

1
मैन पेज को देखते हुए, किल -0 है: "एग्जिट कोड इंगित करता है कि क्या सिग्नल भेजा जा सकता है"। तो क्या यह वास्तव में एक प्रक्रिया को मारता है, या आपको बताता है कि क्या यह मारा जा सकता है?
रिचर्ड एच।

23
killकुछ हद तक इसमें गलतफहमी है कि यह जरूरी प्रक्रिया को नहीं मारता है। यह सिर्फ प्रक्रिया को सिग्नल भेजता है। kill $PIDके बराबर है kill -15 $PID, जो सिग्नल 15, SIGTERM को प्रक्रिया में भेजता है, जो कि समाप्त करने के लिए एक निर्देश है। कोई संकेत 0 नहीं है, यह एक विशेष मान है जो killसिर्फ यह जांचने के लिए कह रहा है कि क्या संकेत को प्रक्रिया में भेजा जा सकता है, जो कि अधिक से अधिक उद्देश्यों के लिए है या कम से कम जाँच के बराबर है यदि यह मौजूद है। देखें linux.die.net/man/2/kill और linux.die.net/man/7/signal
क्रिस्टोफ़र Hammarström

43
यह समस्या है कि यदि प्रक्रिया चल रहे उपयोगकर्ता के स्वामित्व में नहीं है, तो आपके पास किल -0 को कॉल करने की अनुमति नहीं हो सकती है। Ps -p $ PID> / dev / null 2> & 1 का उपयोग करने के लिए बेहतर है, जो आपको प्रक्रिया स्थिति देखने की अनुमति देता है, भले ही आपके पास सिग्नल भेजने की अनुमति न हो।
मस्कॉस

6
@mckoss: उस मामले में वह इसे वैसे भी नहीं मार सकता।
क्रिस्टोफर हैमरस्ट्रॉम

2
इसलिए, मुझे लगता है - उपयोग करने के लिए kill -0, मुझे, वास्तव में, यह करना होगा: kill -0 25667 ; echo $?- और फिर अगर मुझे 0लौटाया जाता है, तो उस पीआईडी ​​के साथ प्रक्रिया को मार दिया जा सकता है; और यदि प्रक्रिया PID (कहना) मौजूद नहीं है, तो विफलता का संकेत $?होगा 1। क्या वो सही है?
सदाउ

264

सबसे अच्छा तरीका है:

if ps -p $PID > /dev/null
then
   echo "$PID is running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
fi

के साथ समस्या:

kill -0 $PID

बाहर निकलने का कोड गैर शून्य होगा भले ही पिड चल रहा हो और आपको इसे मारने की अनुमति न हो। उदाहरण के लिए:

kill -0 1

तथा

kill -0 $non-running-pid

एक सामान्य उपयोगकर्ता के लिए एक अप्रभेद्य (गैर-शून्य) निकास कोड है, लेकिन init प्रक्रिया (PID 1) निश्चित रूप से चल रही है।

चर्चा

मार और दौड़ की स्थिति पर चर्चा करने वाले उत्तर बिल्कुल सही हैं यदि परीक्षण का शरीर "मार" है। मैं सामान्य की तलाश में आया था " आप कैसे बैश में पीआईडी ​​अस्तित्व के लिए परीक्षण करते हैं

/ Proc विधि दिलचस्प है, लेकिन कुछ अर्थों में "ps" कमांड एब्स्ट्रैक्शन की भावना को तोड़ती है, अर्थात आपको न ही इन / प्रूफ़ में जाने की आवश्यकता है क्योंकि क्या होगा यदि लिनुस "एक्स" फ़ाइल को कुछ और कहने का फैसला करता है?


1
ps -p हमेशा मेरे लिए 0 की स्थिति देता है
IttayD

1
ps -p #### ने Ubuntu 14.04 के तहत मेरे लिए ठीक काम किया, +1 धन्यवाद!
Ligemer

3
ps -p हमेशा ओएस एक्स में स्थिति कोड 0 लौटाता है क्योंकि यह प्रक्रिया की एक खाली सूची को प्रिंट करता है जब यह किसी भी चलने की प्रक्रिया से मेल नहीं खाता है
डगलस कोरे

मैं पुष्टि कर सकता हूं कि macOS सिएरा पर, यह काम करता है। इसके अलावा, -pअनावश्यक है, कम से कम उस मामले में। ps $PIDठीक उसी परिणाम है।
user137369

पोर्टेबिलिटी का उपयोग / खरीद से बचने के लिए एक अच्छा कारण है, लेकिन इसके एबीआई को तोड़ने वाला लिनक्स एक ऐसा परिदृश्य नहीं है जिसके बारे में मैं विशेष रूप से चिंता करूंगा।
डेविड राउंडी

67
if [ -n "$PID" -a -e /proc/$PID ]; then
    echo "process exists"
fi

या

if [ -n "$(ps -p $PID -o pid=)" ]

बाद के रूप में, -o pid=बिना किसी हेडर के केवल प्रक्रिया आईडी कॉलम प्रदर्शित करने के लिए आउटपुट स्वरूप है। गैर-रिक्त स्ट्रिंग ऑपरेटर को मान्य परिणाम देने के लिए उद्धरण आवश्यक हैं -n


1
दूसरी विधि मैक पर भी काम करती है, एक अतिरिक्त के रूप में (मैक ओएस एक्स में कोई / खरीद एफएस नहीं है)। हालांकि, आप एक subshell उपयोग करने से बचें और पर दोनों मैक और लिनक्स इस का उपयोग कर सकते हैं:if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
विल

दुर्भाग्य से, psविकल्प और सुविधाएँ प्लेटफार्मों के बीच भिन्न होती हैं, इसलिए यह अभी भी पूरी तरह से पोर्टेबल नहीं है।
ट्रिपल जूल

1
यदि $PIDखाली है तो [ -e /proc/$PID ]अभी भी सही वापस आएगा, क्योंकि /proc/निर्देशिका अभी भी मौजूद है।
मैग्ने

34

psइसके साथ कमांड कर -p $PIDसकते हैं:

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs

11

आपके पास दो तरीके हैं:

मेरे लैपटॉप में एक विशिष्ट एप्लिकेशन की तलाश करके शुरू करें:

[root@pinky:~]# ps fax | grep mozilla
 3358 ?        S      0:00  \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2    S+     0:00              \_ grep mozilla

सभी उदाहरण अब PID 3358 के लिए देखेंगे।

पहला तरीका : "ps aux" चलाएं और दूसरे कॉलम में PID के लिए grep। इस उदाहरण में मैं फ़ायरफ़ॉक्स की तलाश में हूं, और फिर इसके लिए पीआईडी ​​है:

[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358

तो आपका कोड होगा:

if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
    kill $PID 
fi

दूसरा तरीका : बस /proc/$PIDनिर्देशिका में कुछ के लिए देखो । मैं इस उदाहरण में "exe" का उपयोग कर रहा हूं, लेकिन आप कुछ और भी उपयोग कर सकते हैं।

[root@pinky:~]# ls -l /proc/3358/exe 
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash

तो आपका कोड होगा:

if [ -f /proc/$PID/exe ]; then
    kill $PID 
fi

BTW: क्या गलत है kill -9 $PID || true?


संपादित करें:

कुछ महीनों के लिए इसके बारे में सोचने के बाद .. (लगभग 24 ...) मैंने यहां जो मूल विचार दिया, वह एक अच्छा हैक है, लेकिन अत्यधिक महत्वहीन है। हालांकि यह लिनक्स के कुछ कार्यान्वयन विवरणों को सिखाता है, यह मैक, सोलारिस या * बीएसडी पर काम करने में विफल रहेगा। यह भविष्य के लिनक्स कर्नेल पर भी विफल हो सकता है। कृपया - अन्य प्रतिक्रियाओं में वर्णित के रूप में "पीएस" का उपयोग करें।


कम से कम किल -9 वाला हिस्सा गलत लगता है (
सबप्रोसेस

पहला तरीका इस्तेमाल करने पर मुझे [: लापता `] क्यों मिलता है?
टेनमील्स

1
/proc/$PID/exeएक नियमित फ़ाइल नहीं है। इसलिए, [ -f /proc/$PID/exe ]हमेशा एक falseपरिणाम देगा। कोशिश करो [ -h /proc/$PID/exe ]
अलेक्जेंडर यानचुक

8

ऐसा लगता है जैसे आप चाहते हैं

wait $PID

जो $pidखत्म होने पर वापस आ जाएगी ।

अन्यथा आप उपयोग कर सकते हैं

ps -p $PID

यह जाँचने के लिए कि क्या प्रक्रिया अभी भी जीवित है (यह अधिक प्रभावी है kill -0 $pidक्योंकि यह काम करेगा भले ही आप पीआईडी ​​के मालिक न हों)।


1
प्रतीक्षा इतनी प्रभावी नहीं है क्योंकि प्रक्रिया को वर्तमान शेल का बच्चा होना चाहिए या वह देगा:pid 123 is not a child of this shell
कालुमह

7

मुझे लगता है कि यह एक बुरा समाधान है, जो दौड़ की स्थिति के लिए खुलता है। क्या होगा यदि प्रक्रिया आपके परीक्षण और मारने के लिए आपके कॉल के बीच मर जाती है? फिर मारेंगे असफल। तो क्यों न सभी मामलों में हत्या का प्रयास किया जाए, और यह पता लगाने के लिए कि यह कैसे गया, इसकी वापसी मूल्य की जांच करें?


+1 दुर्भाग्य से मारना (1) का निकास कोड अलग-अलग त्रुटि स्थितियों को अलग नहीं करता है (ऐसा लगता है कि यह प्रत्येक प्रक्रिया के लिए एक से बाहर निकलने के मूल्य को बढ़ाता है, यह सिग्नल में विफल रहा)। अगर ओपी को अपनी हत्या (2) रैपर लिखने में कोई आपत्ति नहीं है, तो वह असफल हत्या (2) कॉल के बाद ERRNO के मूल्य के आधार पर विभिन्न मूल्यों के साथ बाहर निकल सकता है।
बस किसी को

फिलहाल मैं बिना किसी जांच के सिर्फ किल -9 कर रहा हूं - अगर मुझे कोई त्रुटि नहीं मिलती है, तो "प्रक्रिया मौजूद नहीं है" अगर यह मौजूद नहीं है तो यह ठीक नहीं है। मैं कैसे परीक्षण करूँगा कि क्या हुआ?
रिचर्ड एच।

14
लापरवाही मत करो kill -9। यह सिर्फ तुरंत ही इस प्रक्रिया को मार देता है जिससे उसे खुद के बाद साफ करने का कोई मौका नहीं मिलता है। इसके बजाय killजो उपयोग के बराबर है kill -15। यदि वह काम नहीं करता है, तो आपको पता लगाना चाहिए कि क्यों, और केवल अंतिम उपाय के रूप में kill -9
क्रिस्टोफ़र हैमरस्ट्रॉम

0

यहाँ मैं PID को एक फ़ाइल में संग्रहीत करता हूँ जिसे .pid कहा जाता है (जो तरह तरह की / रन / ... है) और केवल स्क्रिप्ट निष्पादित करें यदि पहले से ही निष्पादित नहीं किया जा रहा है।

#!/bin/bash
if [ -f .pid ]; then
  read pid < .pid
  echo $pid
  ps -p $pid > /dev/null
  r=$?
  if [ $r -eq 0 ]; then
    echo "$pid is currently running, not executing $0 twice, exiting now..."
    exit 1
  fi
fi

echo $$ > .pid

# do things here

rm .pid

नोट: एक दौड़ की स्थिति है क्योंकि यह जांच नहीं करता है कि उस पिड को कैसे कहा जाता है। यदि सिस्टम को रिबूट किया गया है और .pid मौजूद है, लेकिन एक अलग एप्लिकेशन द्वारा उपयोग किया जाता है, तो यह 'अप्रत्याशित परिणाम' हो सकता है।


0

जीएनयू / लिनक्स में उदाहरण के लिए आप उपयोग कर सकते हैं:

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

या कुछ पसंद है

Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN

और यह आपको ऐप का नाम दिखाता है, बस बिना आईडी का नाम।


1
pidofएक नकारात्मक संख्या वापस नहीं करता है, क्योंकि एक नकारात्मक पीआईडी ​​का कोई मतलब नहीं है, और आप मार नहीं सकते हैं init, इसलिए आपकी सशर्त कोई मतलब नहीं है (और इसके अलावा, आपको >इसे पुनर्निर्देशन करने से रोकने के लिए भागने की आवश्यकता होगी )। आप एक खाली परिणाम के लिए जाँच करना चाहते हैं, लेकिन निश्चित रूप से, किसी भी सभ्य उपकरण की तरह, pidofयह बताने के लिए एक एक्ज़िट कोड सेट करता है कि क्या यह काम किया है, इसलिए उचित समाधान है if Pid=$(pidof 'process_name'); then ...या (यदि आपको Pidबाद में मूल्य की आवश्यकता नहीं होगी ) बसif pidof 'process_name'; then...
ट्रिपल जूल

@tripleee सही pidofउदाहरण है कि कैसे testकाम करता है के बारे में गलतफहमी से भरा है । gnu.org/software/bash/manual/html_node/…
ब्रूनो ब्रोंस्की

0

यदि मेरी प्रक्रिया चल रही है तो नीचे दिए गए कोड, अगर ऐसा कुछ भी नहीं है।

आइए हर घंटे केवल और केवल अमेज़ॅन एसक्यूएस से नए संदेशों की जांच करें, अगर प्रक्रिया नहीं चल रही है।

#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
    /usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
    echo "do nothing, just smile =)"
fi
exit $?
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.