Saya menjalankan beberapa tes menggunakan CentOS 7.1 dan bash. Perhatikan ini berarti huponexit
secara off
default, dan tidak aktif untuk sebagian besar tes saya.
Anda perlu nohup
ketika Anda memulai pekerjaan di terminal, karena jika Anda menutup terminal itu tanpa keluar dari shell dengan bersih , terminal mengirimkan bash sinyal SIGHUP ke shell, yang kemudian mengirimkannya ke semua anak. Jika Anda keluar dari shell dengan bersih - artinya pekerjaan tersebut harus sudah ada di latar belakang sehingga Anda dapat mengetik exit
atau menekan Control-D pada prompt perintah - tidak ada sinyal apa pun yang dikirim ke pekerjaan latar belakang dari bash.
Uji:
Terminal 1
$ echo $$
16779
Terminal 2
$ strace -e signal -p16779
Process 16779 attached
(tutup terminal 1, terlihat di terminal 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 +++
Pekerjaan 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
Mulai di latar belakang di Terminal 1:
Terminal 1
$ ./doit.sh &
[1] 22954
Strace di Terminal 2; tutup Terminal 1 setelah beberapa loop:
Terminal 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
...
Output di Terminal 3:
Terminal 3
out 1
out 2
out 3
HUP
out 4
out 5
out 6
Namun, jika Anda keluar bash
, itu hanya keluar tanpa mengirim sinyal apa pun kepada anak sama sekali. Terminal akan keluar karena tidak lagi memiliki anak, tetapi tentu saja tidak ada orang yang dapat HUP karena shell anak sudah hilang. Itu SIGINT
, SIG_BLOCK
dan SIG_SETMASK
Anda lihat di bawah ini disebabkan oleh sleep
di shell.
Terminal 1
$ ./doit.sh &
26275
Terminal 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
Terminal 3, keluaran
out 1
out 2
out 3
out 4
out 5
out 6
Menariknya, saya mulai huponexit
menggunakan shopt -s huponexit; shopt
(shopt terakhir untuk meninjau), kemudian melakukan tes terakhir, dan lagi-lagi bash tidak mengirim sinyal ke proses latar belakang . Bahkan LEBIH BANYAK bersilangan, seperti yang kita lihat bash memang mengirim sinyal ke proses latar belakang setelah menerimanya dari terminal yang tertutup di wajahnya. Sepertinya huponexit
tidak ada kaitannya dengan satu atau lain cara.
Saya harap ini menghilangkan setiap misteri atau kebingungan mengenai setidaknya hashiness bash, tentang kapan dan bagaimana sinyal HUP dikirim. Setidaknya tes saya benar-benar dapat direproduksi, untuk saya. Saya akan tertarik untuk mengetahui apakah ada pengaturan lain yang mungkin memengaruhi perilaku bash.
Dan, seperti biasa, YSMV (Shell Anda Dapat Bervariasi).
Adendum 1
Ketika saya menjalankan shell as exec /bin/sh
, kemudian jalankan script as /bin/sh ./doit.sh &
, lalu keluar shell dengan bersih, tidak ada sinyal yang dikirim ke pekerjaan latar belakang dan terus berjalan hingga selesai.
Tambahan 2
Ketika saya menjalankan shell as exec /bin/csh
, kemudian jalankan script as /bin/sh ./doit.sh &
, lalu keluar shell dengan bersih, tidak ada sinyal yang dikirim ke pekerjaan latar belakang dan terus berjalan hingga selesai.
--- 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