प्रक्रिया फोर्किंग और निष्पादन के बीच अक्सर भ्रम होता है।
जब आप एक bash
शेल के संकेत पर करते हैं ।
$ sh -c 'exec env ps'
P1 जारी करने वाली प्रक्रिया, जो $
वर्तमान में bash
कोड चला रही है । यह bash
कोड एक नई प्रक्रिया पी 2 की मांग /bin/sh
करता है /usr/bin/env
, जो तब निष्पादित होता है, जो फिर निष्पादित होता है /bin/ps
।
तो P2 बदले में मार डाला गया है के कोड bash
, sh
, env
और ps
।
ps
(या किसी अन्य कमांड जैसे स्क्रिप्ट का उपयोग हम यहां करेंगे) यह जानने का कोई तरीका नहीं है कि इसे env
कमांड द्वारा निष्पादित किया गया है ।
सभी यह पता लगा सकते हैं कि इसकी मूल प्रक्रिया आईडी क्या है, जो कि इस मामले में पी 1 होगी या 1
यदि पी 1 अंतराल में या लिनक्स में किसी अन्य प्रक्रिया में मृत्यु हो गई है जिसे इसके बजाय एक उप-प्रलेखक के रूप में नामित किया गया है 1
।
फिर यह सिस्टम को इस आदेश के लिए क्वेरी कर सकता है कि वर्तमान में क्या प्रक्रिया चल रही है (जैसे readlink /proc/<pid>/exe
लिनक्स पर) या क्या तर्क जहां अंतिम कमांड के लिए पारित किया गया (जैसे ps -o args= -p <pid>
)।
यदि आप चाहते हैं कि आपकी स्क्रिप्ट यह जाने कि इसे क्या कहा गया है, तो एक विश्वसनीय तरीका यह होगा कि हमलावर इसे बताए। उदाहरण के लिए एक पर्यावरण चर के माध्यम से किया जा सकता है। उदाहरण के लिए script1
इस प्रकार लिखा जा सकता है:
#! /bin/sh -
INVOKER=$0 script2 &
और script2
:
#! /bin/sh -
printf '%s\n' "I was invoked by $INVOKER"
# and in this case, we'll probably find the parent process is 1
# (if not now, at least one second later) as script1 exited just after
# invoking script2:
ps -fp "$$"
sleep 1
ps -fp "$$"
exit
$INVOKER
होगा ( आम तौर पर ) के लिए एक रास्ता होता है script1
। कुछ मामलों में, हालांकि यह एक सापेक्ष पथ हो सकता है, और यह पथ उस समय की वर्तमान कार्यशील निर्देशिका के सापेक्ष होगा जो script1
प्रारंभ हुई थी। तो अगर script1
कॉल करने से पहले वर्तमान कार्यशील निर्देशिका बदलता है script2
, script2
क्या यह कहा जाता है के रूप में गलत जानकारी मिल जाएगी। तो यह सुनिश्चित करना बेहतर हो सकता है कि $INVOKER
इसमें एक पूर्ण पथ (अधिमानतः बेसन रखने की तरह) होता है जैसे script1
कि:
#! /bin/sh -
mypath=$(
mydir=$(dirname -- "$0") &&
cd -P -- "$mydir" &&
pwd -P) && mypath=$mypath/$(basename -- "$0") || mypath=$0
... some code possibly changing the current working directory
INVOKER=$mypath script2
POSIX गोले में, $PPID
उस प्रक्रिया के माता-पिता का पिंड सम्मिलित होगा , जो उस शेल आरंभीकरण के समय शेल को निष्पादित करता है। उसके बाद, जैसा कि ऊपर देखा गया है, अगर आईडी की प्रक्रिया $PPID
मर जाती है , तो मूल प्रक्रिया बदल सकती है।
zsh
में zsh/system
मॉड्यूल, क्वेरी कर सकता है वर्तमान के साथ वर्तमान (उप) खोल के माता-पिता पीआईडी $sysparams[ppid]
। POSIX गोले में, आप उस प्रक्रिया का वर्तमान ppid प्राप्त कर सकते हैं जिसने दुभाषिया को निष्पादित किया है (यह मानते हुए कि यह अभी भी चल रहा है ps -o ppid= -p "$$"
। इसके साथ bash
, आप वर्तमान (उप) शेल के pidid के साथ प्राप्त कर सकते हैं ps -o ppid= -p "$BASHPID"
।