मैंने CentOS 7.1 और bash का उपयोग करके कुछ परीक्षण चलाए। ध्यान दें कि इस का मतलब huponexit
है off
डिफ़ॉल्ट रूप से, और मेरे परीक्षण के बहुमत के लिए बंद किया गया था।
आपको nohup
टर्मिनल में नौकरी शुरू करने की आवश्यकता होती है, क्योंकि यदि आप उस टर्मिनल को खोल से बाहर निकाले बिना सफाई से बंद कर देते हैं , तो टर्मिनल शेल को सिग्नल को बैश करता है, जो तब सभी बच्चों को भेजता है। यदि आप शेल को साफ-सुथरे तरीके से बाहर निकालते हैं- तो इसका अर्थ यह है कि जॉब पहले से ही बैकग्राउंड में होनी चाहिए ताकि आप exit
कमांड प्रॉम्प्ट पर Control-D टाइप कर सकें या हिट कर सकें- बैश से बैकग्राउंड जॉब के लिए किसी भी प्रकार का कोई सिग्नल नहीं भेजा जाता है।
परीक्षा:
टर्मिनल 1
$ echo $$
16779
टर्मिनल 2
$ strace -e signal -p16779
Process 16779 attached
(टर्मिनल 1 के करीब, टर्मिनल 2 में देखा गया):
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=16777, si_uid=3000090} ---
rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_SETMASK, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_SETMASK, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], NULL, 8) = 0
rt_sigaction(SIGHUP, {SIG_DFL, [], SA_RESTORER, 0x7f7ace3d9a00}, {0x456880, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], SA_RESTORER, 0x7f7ace3d9a00}, 8) = 0
kill(16779, SIGHUP) = 0
rt_sigreturn() = -1 EINTR (Interrupted system call)
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=16779, si_uid=3000090} ---
+++ killed by SIGHUP +++
नौकरी doit.sh
:
#!/bin/bash
imhupped() {
echo "HUP" >> /tmp/outfile
}
trap imhupped SIGHUP
for i in $(seq 1 6); do echo out $i >> /tmp/outfile; sleep 5; done
इसे टर्मिनल 1 की पृष्ठभूमि में शुरू करें:
टर्मिनल 1
$ ./doit.sh &
[1] 22954
इसे टर्मिनल 2 में स्ट्रेस करें; कुछ छोरों के बाद टर्मिनल 1 बंद करें:
टर्मिनल 2
$ strace -e signal -p22954
Process 22954 attached
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=22980, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn() = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f7a5d547a00}, {0x43e4b0, [], SA_RESTORER, 0x7f7a5d547a00}, 8) = 0
...
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=21685, si_uid=3000090} ---
rt_sigreturn() = -1 EINTR (Interrupted system call)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=23017, si_status=SIGHUP, si_utime=0, si_stime=0} ---
rt_sigreturn() = 0
...
टर्मिनल 3 में आउटपुट:
टर्मिनल 3
out 1
out 2
out 3
HUP
out 4
out 5
out 6
हालाँकि, यदि आप बाहर निकलते हैं bash
, तो यह बिना किसी संकेत के बच्चे को बिल्कुल भेज देता है। टर्मिनल बाहर निकल जाएगा क्योंकि इसमें अब कोई बच्चा नहीं है, लेकिन निश्चित रूप से एचयूपी के लिए कोई नहीं है क्योंकि बच्चा खोल पहले ही चला गया है। SIGINT
, SIG_BLOCK
और SIG_SETMASK
आप नीचे देख के कारण होते हैं sleep
खोल में।
टर्मिनल 1
$ ./doit.sh &
26275
टर्मिनल 2
$ strace -e signal -p26275
Process 26275 attached
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26280, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn() = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0
(..."exit" is typed in bash, notice no new signals sent...)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26303, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn() = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0
टर्मिनल 3, आउटपुट
out 1
out 2
out 3
out 4
out 5
out 6
दिलचस्प बात यह है कि, मैंने समीक्षा करने के लिए (बाद की दुकान) के huponexit
साथ सेट shopt -s huponexit; shopt
किया, फिर अंतिम परीक्षण किया, और फिर से बैश ने पृष्ठभूमि की प्रक्रिया को कोई संकेत नहीं भेजा । इससे भी अधिक समय तक, जैसा कि हमने देखा है कि बैश ने पृष्ठभूमि की प्रक्रिया को संकेत भेजा था , क्योंकि इसे एक टर्मिनल से प्राप्त किया गया था जो उसके चेहरे पर बंद था। ऐसा लगता है जैसे huponexit
एक तरह से या कोई असर नहीं हुआ था।
मुझे आशा है कि यह कम से कम बैश की अनुपस्थिति के बारे में किसी भी रहस्य या भ्रम को हटा देता है, जब एचयूपी सिग्नल कब और कैसे भेजा जाता है। कम से कम मेरे परीक्षण पूरी तरह से प्रतिलिपि प्रस्तुत करने योग्य थे, मेरे लिए। मुझे यह जानने में दिलचस्पी होगी कि क्या कोई अन्य सेटिंग है जो बैश के व्यवहार को प्रभावित कर सकती है।
और, हमेशा की तरह, YSMV (आपका शेल मई वैरी)।
परिशिष्ट 1
जब मैं एक शेल को चलाता हूं exec /bin/sh
, तब स्क्रिप्ट को रन के रूप में चलाता हूं , फिर /bin/sh ./doit.sh &
शेल को साफ तरीके से बाहर निकालें, बैकग्राउंड जॉब के लिए कोई सिग्नल नहीं भेजा जाता है और यह पूरा होने तक चलता रहता है।
परिशिष्ट २
जब मैं एक शेल को चलाता हूं exec /bin/csh
, तब स्क्रिप्ट को रन के रूप में चलाता हूं , फिर /bin/sh ./doit.sh &
शेल को साफ तरीके से बाहर निकालें, बैकग्राउंड जॉब के लिए कोई सिग्नल नहीं भेजा जाता है और यह पूरा होने तक चलता रहता है।
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=10676, si_uid=3000090} --- rt_sigreturn() = -1 EINTR (Interrupted system call) rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0