CentOS 7.1 ve bash kullanarak bazı testler yaptım. Bu araçlar Not huponexit
olduğu off
varsayılan olarak, ve benim testlerin çoğu için kapalı idi.
İhtiyacınız nohup
Bir terminalde bir iş başlattığınızda, çünkü sen yakın temiz kabuk çıkmadan terminali ki eğer , Terminal sonra tüm çocuklara gönderir kabuğuna SIGHUP sinyalini bash gönderir. Kabuktan temiz bir şekilde çıkarsanız exit
, komut isteminde Control-D yazabilmeniz veya bu komutu vurabilmeniz için işin zaten arka planda olması gerekir; bash'dan arka plan işine herhangi bir sinyal gönderilmez.
Ölçek:
Terminal 1
$ echo $$
16779
Terminal 2
$ strace -e signal -p16779
Process 16779 attached
(terminal 2'de görülen terminal 1'i kapatın):
--- 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 +++
Meslek 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
Terminal 1'deki arka planda başlatın:
Terminal 1
$ ./doit.sh &
[1] 22954
Terminal 2'ye yerleştirin; birkaç döngüden sonra Terminal 1'i kapatın:
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
...
Terminal 3'teki çıkış:
Terminal 3
out 1
out 2
out 3
HUP
out 4
out 5
out 6
Ancak, çıkarsanız bash
, çocuğa hiç sinyal göndermeden çıkar. Terminal artık bir çocuğu olmadığı için çıkacak, ancak elbette HUP'a kimse yok çünkü çocuk kabuğu zaten gitti. SIGINT
, SIG_BLOCK
Ve SIG_SETMASK
aşağıda gördüğünüz nedeniyle sleep
kabukta.
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, çıkış
out 1
out 2
out 3
out 4
out 5
out 6
İlginç bir şekilde, (ikinci gözden geçirme için gözden geçirme) huponexit
ile açık olmaya ayarladım shopt -s huponexit; shopt
, daha sonra son testi gerçekleştirdim ve tekrar bash arka plan işlemine sinyal göndermedi . Hatta DAHA interstingly, biz bash gördüğümüz gibi yaptım onun yüzüne kapattığını bir terminalden onu aldıktan sonra arka plan sürecine sinyal gönderecek. Öyle huponexit
ya da böyle bir yönü yoktu gibi görünüyor .
Umarım bu en azından bash'ın huppiness, HUP sinyalinin ne zaman ve nasıl gönderildiği ile ilgili herhangi bir gizemi veya karışıklığı ortadan kaldırır. En azından benim testlerim tamamen tekrarlanabilirdi. Bash'ın davranışını etkileyebilecek başka ayarların olup olmadığını bilmek isterim.
Ve her zaman olduğu gibi, YSMV (Kabuğunuz Değişebilir).
Zeyilname 1
Bir kabuk olarak exec /bin/sh
çalıştırdığımda, komut dosyasını farklı bir şekilde çalıştırdığımda, /bin/sh ./doit.sh &
kabuktan temiz bir şekilde çıkar, arka plan işine hiçbir sinyal gönderilmez ve tamamlanmaya devam eder.
Zeyilname 2
Bir kabuk olarak exec /bin/csh
çalıştırdığımda, komut dosyasını farklı bir şekilde çalıştırdığımda, /bin/sh ./doit.sh &
kabuktan temiz bir şekilde çıkar, arka plan işine hiçbir sinyal gönderilmez ve tamamlanmaya devam eder.
--- 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