मुझे कैसे जांचना चाहिए कि क्या एक दिया गया पीआईडी ​​चल रहा है?


16

मैं एक पर्ल स्क्रिप्ट लिख रहा हूं जो PID को इकट्ठा करने के लिए लॉगफाइल्स को पार्स करता है और फिर जांचता है कि क्या पीआईडी ​​चल रहा है। मैं उस जाँच को करने का सबसे अच्छा तरीका सोचने की कोशिश कर रहा हूँ। जाहिर है, मैं कुछ ऐसा कर सकता था:

system("ps $pid > /dev/null") && print "Not running\n";

हालाँकि, यदि संभव हो तो मैं सिस्टम कॉल से बचना चाहूँगा। इसलिए मैंने सोचा कि मैं /procफाइल सिस्टम का उपयोग कर सकता हूं (पोर्टेबिलिटी एक चिंता का विषय नहीं है, यह हमेशा लिनक्स सिस्टम पर चलता रहेगा)। उदाहरण के लिए:

if(! -d "/proc/$pid"){
    print "Not running\n";
}

क्या वह सुरक्षित है? क्या मैं हमेशा मान सकता हूं कि अगर कोई /proc/$pid/निर्देशिका नहीं है तो संबंधित पीआईडी ​​नहीं चल रही है? मुझे उम्मीद है कि चूंकि AFAIK psको इसकी जानकारी /procवैसे भी मिल जाती है, लेकिन चूंकि यह उत्पादन कोड के लिए है, इसलिए मैं निश्चित होना चाहता हूं।

तो, क्या ऐसे मामले हो सकते हैं जहां किसी चल रही प्रक्रिया की कोई /proc/PIDनिर्देशिका नहीं है या जहां एक /proc/PIDनिर्देशिका मौजूद है और प्रक्रिया नहीं चल रही है? क्या psनिर्देशिका के अस्तित्व के लिए जाँच करने से अधिक पसंद करने का कोई कारण है ?


2
killसिग्नल 0 का उपयोग करके भी पेरल फ़ंक्शन होता है जो कोई हत्या नहीं करता है लेकिन कहता है कि क्या आप ऐसा कर सकते हैं (यानी आपको उस प्रक्रिया को संकेत देने के लिए अनुमति की आवश्यकता है)।
मयूह

1
यदि आप लिनक्स में ऐसा कर रहे हैं तो '/ proc / $ PID' ठीक होना चाहिए।
इसी तरह 17

7
@terdon ध्यान दें कि आप जो भी विधि का उपयोग करते हैं (और kill -0सबसे अच्छा है), यह केवल आपको बताता है कि क्या दिए गए PID के साथ कोई चल रही प्रक्रिया है । यह आपको यह नहीं बताता है कि क्या प्रक्रिया अभी भी एक मिलीसेकंड बाद में चल रही है, और यह आपको यह नहीं बताती है कि क्या प्रक्रिया वह है जिसमें आप रुचि रखते हैं या एक असंबंधित प्रक्रिया है जिसे दिलचस्प प्रक्रिया के बाद उसी पीआईडी ​​को सौंपा गया है । यह हमेशा परीक्षण करने के लिए लगभग एक गलती है कि क्या किसी दिए गए पीआईडी ​​चल रहा है : बहुत कम परिस्थितियां हैं जहां यह दौड़ की स्थिति से ग्रस्त नहीं है।
गिल्स एसओ- बुराई को रोकना '

1
@ गिल्स वास्तव में, मुझे प्रक्रिया का नाम भी जांचना चाहिए। हालाँकि, इस मामले में, मुझे परवाह नहीं है कि बाद में कोई स्थिति मिलीसेकंड में बदल जाती है। मेरे पास एक dB में सक्रिय प्रक्रियाएं हैं और pids के साथ एक संबंधित फ़ाइल है। मुझे बस यह जांचने की जरूरत है कि क्या डीबी को लगता है कि कुछ भी नहीं चल रहा है, वास्तव में नहीं चल रहा है और यह जानने के लिए सेटअप पर पर्याप्त नियंत्रण है कि यह यादृच्छिक रूप से शुरू नहीं हो सकता है।
terdon

3
@MickLH वाह, यह मुझे बताया गया है। यह वास्तव में आपकी खुद की प्रतिभा के उत्सव के बजाय एक उपयोगी टिप्पणी होगी जो आपको यह समझाने के लिए परेशान करती है कि क्या इतना बुरा और खतरनाक है। मुझे संदेह नहीं है कि आप सही हैं, मैंने कभी भी एक प्रोग्रामर होने का दावा नहीं किया है, यही वजह है कि मैंने सवाल पूछा, लेकिन आप अपमानजनक और अनहेल्दी दोनों होने में कामयाब रहे।
terdon

जवाबों:


20

पर्ल फ़ंक्शन kill(0,$pid)का उपयोग किया जा सकता है।

यदि रिटर्न कोड 1 है तो पीआईडी ​​मौजूद है और आपको इसके लिए एक संकेत भेजने की अनुमति है।

यदि रिटर्न कोड 0 है तो आपको $ चेक करने की आवश्यकता है! यह EPERM (अनुमति से वंचित) हो सकता है जिसका अर्थ है कि प्रक्रिया मौजूद है या ESRCH जिस स्थिति में प्रक्रिया मौजूद नहीं है।

यदि आपका चेकिंग कोड चल रहा है, rootतो आप इसे केवल कोड ऑफ किल को चेक करने के लिए सरल कर सकते हैं; 0 => त्रुटि, 1 => ठीक है

उदाहरण के लिए:

% perl -d -e 0

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(-e:1):   0
  DB<1> print kill(0,500)
0
  DB<2> print $!
No such process
  DB<3> print kill(0,1)
0
  DB<4> print $!
Operation not permitted
  DB<5> print kill(0,$$)
1

इसे एक साधारण फंक्शन में बनाया जा सकता है

use Errno;

sub test_pid($)
{
  my ($pid)=@_;

  my $not_present=(!kill(0,$pid) && $! == Errno::ESRCH);

  return($not_present);
}

print "PID 500 not present\n" if test_pid(500);
print "PID 1 not present\n" if test_pid(1);
print "PID $$ not present\n" if test_pid($$);

एफडब्ल्यूआईडब्ल्यू, मैंने एक साधारण फ़ंक्शन जोड़ा, जिसमें दिखाया गया है कि आप यह कैसे कर सकते हैं।
स्टीफन हैरिस

हाँ, मुझे लगता है कि मैं इसके साथ जाऊँगा। मैंने अपनी टिप्पणी को हटा दिया क्योंकि मुझे एहसास हुआ कि मुझे जो चाहिए था if (!kill(0,$pid) && $! =~ /No such process/){ exit; }या समान था । मुझे आपका Errnoसमाधान बेहतर लगता है, धन्यवाद। हालांकि मैं शायद इसके साथ जाऊंगा, लेकिन जब भी कोई व्यक्ति अंतर्निहित लिनक्स प्रश्न का उत्तर दे सकता है, मैं प्रतीक्षा करूंगा।
terdon

2
यदि /procमाउंट किया गया है तो नाम स्थान में दिखाई देने वाला हर पीआईडी ​​मौजूद होगा, इसलिए आपका -d /proc/$pidपरीक्षण काम करेगा ... लेकिन इसमें मूल सिस्टम कॉल का उपयोग करने के बजाय फाइल सिस्टम में शामिल होना शामिल है।
स्टीफन हैरिस

जो ठीक वही है जो मैं बचना चाहता था, हाँ।
terdon

2
@terdon: मुझे एहसास हुआ कि मेरी भ्रम की स्थिति इस तथ्य से है कि "सिस्टम कॉल" द्वारा आप वास्तव में " systemकॉल" का मतलब है - यानी, systemफ़ंक्शन के लिए एक कॉल , न कि "सिस्टम कॉल" । उत्तरार्द्ध आप से बच नहीं सकते हैं, लेकिन पूर्व आप निश्चित रूप से कर सकते हैं। अब समझ में आता है!
user541686

6
  • मुझे 99.9% यकीन है कि जाँचना मौजूद है (और एक निर्देशिका है) तकनीक के रूप में 98% विश्वसनीय है । 98% 100% नहीं होने का कारण यह है कि स्टीफन हैरिस ने एक टिप्पणी में (और बाउंस ऑफ) को छुआ - अर्थात्, फाइल सिस्टम माउंट नहीं किया जा सकता है। यह दावा करने के लिए मान्य हो सकता है कि बिना एक Linux सिस्टम एक क्षतिग्रस्त, अवक्रमित प्रणाली है - सभी के बाद, चीजों की तरह है , और शायद काम नहीं करेगा - और इसलिए इस पराक्रम एक उत्पादन प्रणाली के लिए एक मुद्दा नहीं हो। लेकिन यह (सैद्धांतिक रूप से) संभव है कि इसे कभी भी माउंट नहीं किया गया है (हालांकि यह सिस्टम को सामान्य स्थिति में आने से रोक सकता है), यह निश्चित रूप से संभव है कि इसे अनमाउंट किया जाए (मैंने इसे परीक्षण किया है 1/proc/PIDkill 0/proc/procpstoplsof), और मेरा मानना ​​है कि इसकी कोई गारंटी नहीं है कि यह मौजूद होगा (यानी, यह POSIX द्वारा आवश्यक नहीं है)। और, जब तक सिस्टम पूरी तरह से ठीक नहीं हो जाता है, तब तक killकाम करेगा।
  • स्टीफन की टिप्पणी "फाइलसिस्टम से बाहर जाने" और "देशी प्रणाली कॉल का उपयोग करने" के बारे में बात करती है। मेरा मानना ​​है कि यह काफी हद तक एक लाल हेरिंग है।
    • हां, एक्सेस के किसी भी प्रयास के लिए फाइल सिस्टम खोजने के /proc लिए रूट डायरेक्टरी को पढ़ना पड़ता है। यह सच किसी भी प्रयास का उपयोग करने के लिए है किसी भी में बातें भी शामिल है, एक पूर्ण पथ नाम से फ़ाइल , , और । ऐसा अक्सर होता है कि सिस्टम के पूरे जीवनकाल (अपटाइम) के लिए रूट डायरेक्टरी निश्चित रूप से मेमोरी में कैश की जाती है, इसलिए यह स्टेप बिना किसी डिस्क I / O के किया जा सकता है। और, एक बार जब आपके पास इनकोड होता है, तो बाकी सब कुछ जो स्मृति में होता है।/proc/bin/etc/dev/proc
    • आप कैसे पहुँच सकते हैं /proc? साथ stat, open, readdir, आदि, देशी प्रणाली के रूप में ज्यादा के रूप में हर बिट कॉल कर रहे हैं जो kill
  • सवाल चल रही प्रक्रिया के बारे में बात करता है। यह एक फिसलन वाक्यांश है। यदि आप वास्तव में परीक्षण करना चाहते हैं कि क्या प्रक्रिया चल रही है (यानी, रन कतार में; शायद कुछ चार्जर पर वर्तमान प्रक्रिया; नींद नहीं, इंतजार, या रुका हुआ), तो आपको आउटपुट करने और पढ़ने या देखने की आवश्यकता हो सकती है । । लेकिन मुझे आपके प्रश्न या टिप्पणियों में कोई संकेत नहीं दिखता है कि आप इससे चिंतित हैं।ps PID /proc/PID/stat

    कमरे में हाथी, हालांकि, यह है कि एक ज़ोंबी 2 प्रक्रिया एक ऐसी प्रक्रिया से भेद करना मुश्किल हो सकती है जो जीवित और अच्छी तरह से है।  kill 0एक ज़ोंबी पर काम करता है, और मौजूद है। आप पिछले पैराग्राफ में सूचीबद्ध तकनीकों ( आउटपुट को पढ़ने और पढ़ने, या देखने ) के साथ लाश की पहचान कर सकते हैं । मेरे बहुत जल्दी और आकस्मिक (यानी, बहुत ही गहन नहीं) परीक्षण से पता चलता है कि आप भी एक कर ऐसा कर सकते हैं कि या पर , या - इन लाश पर असफल हो जायेगी। (हालांकि, वे उन प्रक्रियाओं पर भी विफल हो जाएंगे जो आपके पास नहीं हैं।)/proc/PIDps PID/proc/PID/statreadlinklstat/proc/PID/cwd/proc/PID/root/proc/PID/exe

____________
1  अगर -f( f orce) विकल्प काम नहीं करता है, तो कोशिश करें -l( l azy)।
2  यानी, एक ऐसी प्रक्रिया जो बाहर हो गई है / मर गई है / समाप्त हो गई है, लेकिन जिनके माता-पिता ने अभी तक नहीं किया है wait


मेरे उत्तर पर आपकी टिप्पणी के लिए धन्यवाद, जिसे मैंने हटा दिया है क्योंकि यह गलत था। मेरा मानना ​​है कि kill(2)मैनपेज सीधे आपके द्वारा बताए गए व्यवहार को इंगित करता है, लेकिन perlfuncमैनपेज करता है। मैं माइकल केरिस्क को ईमेल करके देखूंगा कि सिस्टम मैनपेज के बारे में उनका क्या कहना है।
jrw32982

मैं एक बग रिपोर्ट दायर करने के लिए के लिए मानव पेज स्पष्ट kill(2)"भेजें" संकेत 0 पर अनुमतियों के बारे में
jrw32982 का समर्थन करता है मोनिका

@ jrw32982: ठीक है, आदमी पेज बातें, पसंद "कहते हैं sig तर्क ... 0 हो सकता है, ऐसी स्थिति में त्रुटि जाँच ... किया जाता है" और " त्रुटियों - मार () सिस्टम कॉल विफल हो जाएगा और कोई संकेत करता है, तो भेजा जाएगा: … भेजने की प्रक्रिया सुपर-उपयोगकर्ता नहीं है और इसकी प्रभावी उपयोगकर्ता आईडी प्राप्त करने की प्रक्रिया के प्रभावी उपयोगकर्ता-आईडी से मेल नहीं खाती है। ... "अब जब आप इसका उल्लेख करते हैं, तो मुझे लगता है कि इसकी व्याख्या एक से अधिक तरीकों से की जा सकती है, लेकिन, अफसोस की बात है कि कई यूनिक्स मैन पेज इस शैली में लिखे गए हैं, जो आपको लाइनों के बीच पढ़ने की आवश्यकता है। माइकल मान सकते हैं कि यह काफी स्पष्ट है जैसा कि यह है।
जी-मैन का कहना है कि 'मोनिका'

माइकल ने kill(2)मैनपेज में बदलाव किया (मैं इसे अभी तक ऑनलाइन नहीं देख रहा हूं): "यदि सिग 0 है, तो कोई संकेत नहीं भेजा जाता है, लेकिन अस्तित्व और अनुमति की जांच अभी भी की जाती है; इसका उपयोग अस्तित्व की जांच के लिए किया जा सकता है। प्रक्रिया आईडी या प्रक्रिया समूह आईडी जिसे कॉल करने वाले को संकेत देने की अनुमति है। "
jrw32982
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.