আমি CentOS 7.1 এবং ব্যাশ ব্যবহার করে কিছু পরীক্ষা চালিয়েছি। উল্লেখ্য এর মানে huponexit
হল off
ডিফল্ট ভাবে, আর আমার পরীক্ষার সংখ্যাগরিষ্ঠ জন্য বন্ধ ছিল।
আপনি nohup
যখন কোনও টার্মিনালে কাজ শুরু করবেন তখন আপনার প্রয়োজন হবে , কারণ আপনি যদি শেলটি পরিষ্কার না ছাড়াই টার্মিনালটি বন্ধ করেন তবে টার্মিনালটি শ্যালে সিএইচএইচপি সংকেত পাঠায়, যা পরে এটি সমস্ত শিশুদের কাছে প্রেরণ করে। আপনি যদি শেলটি পরিষ্কারভাবে প্রস্থান করেন - এর অর্থ চাকরিটি ইতিমধ্যে পটভূমিতে থাকতে হবে যাতে আপনি exit
কমান্ড প্রম্পটে কন্ট্রোল-ডি টাইপ করতে বা হিট করতে পারেন ash বাশ থেকে কোনও ধরণের কোনও সংকেত ব্যাকগ্রাউন্ড জবটিতে প্রেরণ করা হয় না।
টেস্ট:
বন্দর 1
$ echo $$
16779
টার্মিনাল ২
$ 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 বন্ধ করুন:
টার্মিনাল ২
$ 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
টার্মিনাল ২
$ 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
(পর্যালোচনার আধুনিক shopt) তাহলে শেষ টেস্ট সঞ্চালিত, এবং আবার ব্যাশ পটভূমি প্রক্রিয়া কোন সংকেত পাঠানো । এমনকি আরও interstingly, যেমন আমরা ব্যাশ দেখেছি করেনি পটভূমি প্রক্রিয়া সংকেত পাঠাতে পরে এটি একটি টার্মিনাল যে তার মুখে বন্ধ থেকে এটা পেয়েছি। দেখে মনে হচ্ছে যেন huponexit
কোনওভাবেই বা অন্য কোনওভাবেই তার জন্মেনি।
আমি আশা করি এটি কমপক্ষে বাশের সুখ সম্পর্কে কোনও রহস্য বা বিভ্রান্তি দূর করে, কখন এবং কীভাবে এইচপি সংকেত পাঠানো হয় about কমপক্ষে আমার পরীক্ষাগুলি আমার জন্য সম্পূর্ণ পুনরুত্পাদনযোগ্য ছিল। বাশের আচরণকে প্রভাবিত করতে পারে এমন অন্য কোনও সেটিংস রয়েছে কিনা তা জানতে আগ্রহী।
এবং, সর্বদা হিসাবে, ওয়াইএসএমভি (আপনার শেল মে পরিবর্তিত হতে পারে)।
সংযোজন ঘ
আমি যখন শেলটি চালিত করি exec /bin/sh
তখন স্ক্রিপ্টটি এর মতো চালান /bin/sh ./doit.sh &
, তারপরে শেলটি পরিষ্কার করে প্রস্থান করুন, ব্যাকগ্রাউন্ড জবটিতে কোনও সংকেত প্রেরণ করা হয় না এবং এটি সমাপ্তির দিকে চালিয়ে যেতে থাকে।
সংযোজন 2
আমি যখন শেলটি চালিত করি 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