मैं हाल ही में एक शेल स्क्रिप्ट में इस पर आया था।
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
क्या करता kill -0 ...
है?
kill -0 $pid
है? के रूप में अच्छी तरह से क्या करता है 0 वास्तव में मार डालते हैं? ।
मैं हाल ही में एक शेल स्क्रिप्ट में इस पर आया था।
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
क्या करता kill -0 ...
है?
kill -0 $pid
है? के रूप में अच्छी तरह से क्या करता है 0 वास्तव में मार डालते हैं? ।
जवाबों:
यह चमकाने के लिए थोड़ा कठिन है, लेकिन यदि आप निम्नलिखित 2 मैन पेजों को देखेंगे तो आपको निम्नलिखित नोट दिखाई देंगे:
मारने (1)$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
को मारने के (2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed;
this can be used to check for the existence of a process ID or process
group ID.
...
तो संकेत 0 वास्तव में वास्तव में आपकी प्रक्रिया के पीआईडी के लिए कुछ भी नहीं भेजेगा, लेकिन यह जांच करेगा कि क्या आपके पास ऐसा करने की अनुमति है।
एक स्पष्ट स्थान होगा यदि आप यह निर्धारित करने की कोशिश कर रहे थे कि क्या आपके पास रनिंग प्रक्रिया के लिए सिग्नल भेजने की अनुमति है kill
। आप वास्तविक kill
सिग्नल भेजने से पहले जांच कर सकते हैं कि आप क्या चाहते हैं, यह सुनिश्चित करने के लिए चेक लपेटकर कि kill -0 <PID>
पहले अनुमति दी गई थी।
मान लें कि एक प्रक्रिया रूट द्वारा चलायी जा रही है:
$ sudo sleep 2500 &
[1] 15693
अब एक अन्य विंडो में अगर हम इस कमांड को चलाते हैं तो हम पुष्टि कर सकते हैं कि पीआईडी चल रहा है।
$ pgrep sleep
15693
अब इस कमांड को यह देखने की कोशिश करते हैं कि क्या हमारे पास उस PID सिग्नल को भेजने के लिए एक्सेस है kill
।
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
तो यह काम करता है, लेकिन आउटपुट kill
कमांड से एक संदेश लीक कर रहा है कि हमारे पास अनुमति नहीं है। कोई बड़ी बात नहीं है, बस STDERR को पकड़ें और उसे भेजें /dev/null
।
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
तो फिर हम कुछ ऐसा कर सकते हैं killer.bash
:
#!/bin/bash
PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then
echo "you don't have permissions to kill PID:$PID"
exit 1
fi
kill -9 $PID
अब जब मैं उपर्युक्त को बिना रूट उपयोक्ता के रूप में चलाता हूं:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
हालाँकि जब इसे रूट के रूप में चलाया जाता है:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
, ps
पार्सिंग या test -e /proc/$PID
पोर्टेबल स्क्रैप में, लेकिन kill -0
हर जगह काम करता है। यदि आपको एक पीआईडी दी गई है जो बासी हो सकती है - जैसे एक /var/run
प्रविष्टि - यह जांचने का पोर्टेबल तरीका है कि क्या प्रक्रिया अभी भी जीवित है।
kill -0 $(pgrep sleep)
जरूरी नहीं कि असफल होने का मतलब यह हो कि आप कमजोर हैं , अगर कोई sleep
कमांड नहीं चल रही है, तो यह झूठी हो जाएगी या यदि एक से अधिक हैं और कोई ऐसा नहीं है जिसे आप नहीं मार सकते हैं, या यदि नींद में से कोई एक पग्रेप और किल के बीच मर जाता है कमांड चलाए जा रहे हैं।
kill -0
(या इसके अधिक पोर्टेबल POSIX संस्करण kill -s 0
) एक संकेत भेजने की गति से गुजरता है, लेकिन वास्तव में एक नहीं भेजता है। यह अंतर्निहित C API की एक विशेषता है जो शेल कमांड सीधे तरीके से उजागर होती है।
kill -s 0 -- "$pid"
इस प्रकार यह परीक्षण करता है कि क्या दिए गए पीआईडी (या पीजीआईडी यदि $pid
नकारात्मक है) के साथ एक चल रही प्रक्रिया है , और क्या वर्तमान प्रक्रिया को इसे भेजने की अनुमति होगी (नकारात्मक होने की स्थिति में प्रक्रिया समूह में कोई भी प्रक्रिया $pid
)। यह ज्यादातर परीक्षण का एक तरीका है कि क्या एक प्रक्रिया (या प्रक्रिया समूह) जीवित है।
ध्यान रखें कि भले ही अपेक्षित पीआईडी और अनुमतियों के साथ कोई प्रक्रिया चल रही हो, लेकिन जरूरी नहीं कि यह वह प्रक्रिया हो, जिसकी आप अपेक्षा करते हैं। यह संभव है कि आप जिस प्रक्रिया की अपेक्षा करते हैं, वह पहले ही मर गई हो और उसका पीआईडी एक असंबंधित प्रक्रिया के लिए पुन: उपयोग किया गया हो। प्रक्रियाओं की निगरानी का सही तरीका उनके माता-पिता को यह करने से है - एक प्रक्रिया के PID का पुन: उपयोग नहीं किया जाता है जब तक कि उसके माता-पिता ने उसकी मृत्यु को स्वीकार नहीं किया है (इसलिए लाश मौजूद है), इसलिए एक प्रक्रिया के माता-पिता अपने बच्चों को उनके PID द्वारा मज़बूती से पहचान सकते हैं।
kill -0 $pid
आपको बताता है कि एक प्रक्रिया के साथ $pid
मौजूद है।
स्निपेट में
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
ब्लॉक ... do something ...
को निष्पादित किया जाता है यदि PID के साथ एक प्रक्रिया जो संग्रहीत की जाती /path/to/file.pid
है - और - जब तक कि स्निपेट रूट के रूप में नहीं चलता - यदि PID एक ही उपयोगकर्ता के अंतर्गत चलता है।
POSIX मानक 0
संकेत की भूमिका को निर्दिष्ट करता है :
यदि sig 0 (शून्य संकेत) है, तो त्रुटि जाँच की जाती है, लेकिन वास्तव में कोई संकेत नहीं भेजा जाता है। शून्य संकेत का उपयोग पीआईडी की वैधता की जांच के लिए किया जा सकता है।
(मार (3p), POSIX.1-2008 - POSIX.1-2001 में इसी तरह का शब्दांकन)
ध्यान दें कि POSIX दोनों kill -0
और kill -s 0
कमांड लाइन शैलियों (किल (1p)) को निर्दिष्ट करता है ।
किल syscall इंटरफ़ेस के विपरीत, kill
कमांड का उपयोग अन्य उपयोगकर्ताओं (सामान्य उपयोगकर्ता के रूप में) के स्वामित्व वाले PID के अस्तित्व के लिए मज़बूती से जांचने के लिए नहीं किया जा सकता है, जैसे:
$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1
बनाम
$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1
जब मार syscall एक मज़बूती से इन मामलों में अंतर देख सकते हैं errno
मूल्य (cf. जैसे एक पायथन उदाहरण )।
trap
कमांड और 0 से एक संकेत 0 बनामkill
: एक ट्रैप कमांड में सिग्नल 0 क्या है?