क्या लॉगिंग प्रक्रिया के दौरान बैकग्राउंड प्रोसेस को SIGHUP मिलता है?


21

यह इस सवाल का फॉलोअप है ।

मैंने कुछ और परीक्षण चलाए हैं; ऐसा लगता है कि यह वास्तव में कोई फर्क नहीं पड़ता अगर यह भौतिक कंसोल पर या एसएसएच के माध्यम से किया जाता है, न तो यह केवल एससीपी के साथ ही होता है; मैंने इसके साथ परीक्षण भी किया cat /dev/zero > /dev/null। व्यवहार बिल्कुल वैसा ही है:

  • उपयोग करने के बाद पृष्ठभूमि में एक प्रक्रिया शुरू करें &(या इसे उपयोग करने के बाद पृष्ठभूमि में डालें CTRL-Zऔर bg); यह उपयोगnohup किए बिना किया जाता है ।
  • लॉग ऑफ।
  • फिर से लॉग ऑन करें।
  • यह प्रक्रिया अभी भी जारी है, खुशी से चल रही है, और अब का प्रत्यक्ष बच्चा है init

अगर भेजा जाए तो मैं एससीपी और कैट दोनों तुरंत पुष्टि कर सकता हूं SIGHUP; मैंने इसका उपयोग करके परीक्षण किया kill -HUP

तो, यह वास्तव में ऐसा लगता है कि साइटअप लॉगऑफ़ पर नहीं भेजा गया है, कम से कम पृष्ठभूमि प्रक्रियाओं के लिए (स्पष्ट विवरण के लिए अग्रभूमि के साथ परीक्षण नहीं कर सकता है)।

यह शुरुआत में VMware ESX 3.5 (जो RedHat पर आधारित है) के सर्विस कंसोल के साथ हुआ था, लेकिन मैं इसे CentOS 5.4 पर बिल्कुल दोहराने में सक्षम था।

सवाल यह है कि, फिर से: एक SIGHUP को प्रक्रियाओं में नहीं भेजा जाना चाहिए, भले ही वे पृष्ठभूमि में चल रहे हों, लॉग ऑफ करने पर? ऐसा क्यों नहीं हो रहा है?


संपादित करें

मैंने straceकाइल के उत्तर के अनुसार जाँच की।
जैसा कि मैं उम्मीद कर रहा था, इस प्रक्रिया को कोई संकेत नहीं मिलता है जब शेल से लॉग इन किया गया था जहां इसे लॉन्च किया गया था। यह सर्वर के कंसोल का उपयोग करते समय और SSH के माध्यम से दोनों होता है।


सेंटोस 7.1 पर बैश का उपयोग करते हुए, एक सरल शेल स्क्रिप्ट लूप को यदि अंडरग्राउंड में छोड़ दिया जाता है, तो उसे एक SUPUP मिल जाएगा, लेकिन टर्मिनल मारा गया; एक और टर्मिनल शो से स्ट्रेस: --- 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
माइक एस

तो एक बैकग्राउंड स्क्रिप्ट होगी। ध्यान दें कि लूप एक नींद पर इंतजार कर रहा है, जबकि टर्मिनल बंद है। खोल बाहर नहीं निकलता है:--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=13944, si_uid=3000090} --- +++ killed by SIGHUP +++
माइक एस

परीक्षणों के लिए मेरा उत्तर देखें। दिलचस्प बात यह है कि मैंने व्यवहार में कोई बदलाव नहीं देखा huponexit
माइक एस

जवाबों:


26

उत्तर मिला।

BASH के लिए, यह huponexitशेल विकल्प पर निर्भर करता है , जिसे अंतर्निहित shoptकमांड का उपयोग करके देखा और / या सेट किया जा सकता है ।

ऐसा लगता है कि यह विकल्प डिफ़ॉल्ट रूप से बंद है, कम से कम RedHat- आधारित सिस्टम पर।

BASH मैन पेज पर अधिक जानकारी :

किसी SIGHUP के प्राप्त होने पर शेल डिफ़ॉल्ट रूप से बाहर निकलता है। बाहर निकलने से पहले, एक इंटरेक्टिव शेल सभी जॉब के लिए, रनिंग या रोके जाने के लिए SITEUP का समाधान करता है। बंद नौकरियों को SIGCONT भेजा जाता है ताकि यह सुनिश्चित हो सके कि वे SIGHUP प्राप्त करते हैं। शेल को किसी विशेष कार्य के लिए सिग्नल भेजने से रोकने के लिए, इसे जॉब टेबल से हटाए गए बिलिन के साथ हटा दिया जाना चाहिए (नीचे दिए गए SHIL BUILTIN COMMANDS देखें) या disown -h का उपयोग करके SIGHUP प्राप्त नहीं करने के लिए चिह्नित किया गया है।

यदि हूपोनेक्सिट शेल विकल्प को शॉपट के साथ सेट किया गया है, तो बैश एक इंटरेक्टिव लॉग इन एक्स्टिट होने पर सभी जॉब के लिए एक साइट भेजता है।


4
सत्यापित। जब मैंने "एक्जिट", "लॉगआउट", या सीटीएल-डी को बच्चे की खरीद (नौकरी) किया, तो उसे एक साइनअप (रूट और रेग उपयोगकर्ता दोनों) प्राप्त नहीं होगा। हालांकि जब मैंने बच्चे को मारने की वर्तमान आवृत्ति को मारने के लिए "किल-हप $ वॉट" किया, तो डीआईडी ​​को एक उच्छ्वास प्राप्त होता है। मैंने तब huponexit सेट किया और बाहर निकलने पर बच्चे की प्रक्रिया को SIGHUP प्राप्त हुआ।
कार्पेक्टोक्टेम

3

इसे मेरे परीक्षणों में SITEUP भेजा जाएगा:

Shell1:

[kbrandt@kbrandt-opadmin: ~] ssh localhost
[kbrandt@kbrandt-opadmin: ~] perl -e sleep & 
[1] 1121
[kbrandt@kbrandt-opadmin: ~] ps
  PID TTY          TIME CMD
 1034 pts/46   00:00:00 zsh
 1121 pts/46   00:00:00 perl
 1123 pts/46   00:00:00 ps

Shell2:

strace -e trace=signal -p1121

शेल 1 फिर:

[kbrandt@kbrandt-opadmin: ~] exit
zsh: you have running jobs.
[kbrandt@kbrandt-opadmin: ~] exit
zsh: warning: 1 jobs SIGHUPed
Connection to localhost closed.

शेल 2 फिर से :

strace -e trace=signal -p1121
Process 1121 attached - interrupt to quit
pause()                                 = ? ERESTARTNOHAND (To be restarted)
--- SIGHUP (Hangup) @ 0 (0) ---
Process 1121 detached

यह अभी भी क्यों चलता है ?:
स्टीवंस द्वारा यूनिक्स पर्यावरण में उन्नत प्रोग्रामिंग धारा 9.10 के तहत इसे शामिल करता है: अनाथ प्रक्रिया समूह। सबसे अधिक प्रासंगिक अनुभाग:

चूँकि जब पेरेंट समाप्त हो जाता है तो प्रक्रिया समूह अनाथ हो जाता है, POSIX.1 को आवश्यक है कि नव अनाथ प्रक्रिया समूह में हर प्रक्रिया जो रोकी जाती है (जैसा कि हमारा बच्चा है) को हैंग-अप सिग्नल (SIGHUP) भेजा जाए, इसके बाद जारी सिग्नल (SIGCONT) )।

यह हैंग-अप सिग्नल को संसाधित करने के बाद बच्चे को जारी रखने का कारण बनता है। हैंग-अप सिग्नल के लिए डिफ़ॉल्ट कार्रवाई प्रक्रिया को समाप्त करना है, इसलिए हमें सिग्नल को पकड़ने के लिए सिग्नल हैंडलर प्रदान करना होगा। इसलिए हम pr_ids फ़ंक्शन में प्रिंट के सामने आने के लिए sig_hup फ़ंक्शन में प्रिंटफ़ की अपेक्षा करते हैं।


लेकिन आपने स्पष्ट रूप से इसे यहां एक SITEUP भेजा है; मैं इस बारे में बात कर रहा था कि जब आप प्रक्रिया शुरू करते हैं तो शेल से लॉग ऑफ करते समय क्या होता है।
मासिमा

जब मैं बाहर निकलता हूं तो समान परिणाम, हालांकि मुझे नौकरियों के बारे में चेतावनी मिलती है, लेकिन फिर से बाहर निकलें। मैंने ZSH के साथ इसका परीक्षण किया।
काइल ब्रान्ड

मैं BASH का उपयोग कर रहा हूं, और यह संभवतः शेल पर निर्भर करता है। लेकिन BASH को लॉग इन करते समय चाइल्ड प्रोसेस में SITEUP भेजना चाहिए ...
मासिमो

अगर नौकरी रोक दी जाती है तो बैश जाहिर तौर पर SIGCONT भेजता है, लेकिन मैं इसकी पुष्टि करता हूं कि अगर नौकरी नहीं रोकी गई तो वह कुछ भी नहीं भेजेगा।
काइल ब्रान्ड

सेंटोस 7.1 पर बैश का उपयोग करते हुए, मुझे एक और विंडो में रोकी गई मेरी प्रक्रिया के लिए भेजा गया एक SIGTERM मिलता है: 1.) सरल शेल स्क्रिप्ट शुरू करें (एक प्रतिध्वनि और नींद के साथ लूप), 2.) नियंत्रण-जेड यह, 3) प्रक्रिया में स्ट्रेस प्रक्रिया एक और खिड़की, 4) मूल टर्मिनल से बाहर निकलें। यह शिकायत करता है कि मेरे पास काम चल रहा है, फिर मेरे स्ट्रेस शो से बाहर निकलने के बाद: $ strace -e signal -p1705 Process 1705 attached --- stopped by SIGTSTP --- --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=791, si_uid=3000090} --- +++ killed by SIGTERM +++ अजीब, निश्चित रूप से स्टीवंस के उद्धृत खंड के अनुरूप नहीं है।
माइक एस

2

मैंने 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 &शेल को साफ तरीके से बाहर निकालें, बैकग्राउंड जॉब के लिए कोई सिग्नल नहीं भेजा जाता है और यह पूरा होने तक चलता रहता है।


0

जब मैं लॉगऑफ़ करता हूं तो मैं csh और बैकग्राउंड प्रोसेस का उपयोग जारी रखता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.