ฉันรันการทดสอบบางอย่างโดยใช้ CentOS 7.1 และทุบตี โปรดทราบว่าวิธีการนี้huponexit
เป็นoff
ค่าเริ่มต้นและปิดการทดสอบส่วนใหญ่ของฉัน
คุณต้องnohup
เมื่อคุณเริ่มต้นงานในขั้วเพราะถ้าคุณใกล้ที่ขั้วโดยไม่ออกจากเปลือกเรียบร้อยที่สถานีส่งสัญญาณทุบตี SIGHUP กับเปลือกที่แล้วส่งไปให้เด็กทุกคน หากคุณออกจาก shell cleanly- หมายถึงงานต้องอยู่ในพื้นหลังอยู่แล้วดังนั้นคุณสามารถพิมพ์exit
หรือกด Control-D ที่ command prompt - ไม่มีสัญญาณของการเรียงลำดับใด ๆ ที่ถูกส่งไปยังงานแบ็คกราวน์จาก bash
ทดสอบ:
อาคาร 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
มันก็จะออกโดยไม่ส่งสัญญาณใด ๆ ไปยังเด็กเลย เทอร์มินัลจะออกเพราะไม่มีลูกอีกต่อไป แต่แน่นอนว่าไม่มีใครที่จะ HUP เพราะเปลือกลูกหายไปแล้ว 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
(คน shopt หลังตรวจสอบ) แล้วดำเนินการทดสอบที่ผ่านมาและอีกครั้งทุบตีส่งสัญญาณไปยังกระบวนการพื้นหลังไม่มี ยิ่งขัดจังหวะมากขึ้นเท่าที่เราเห็นทุบตีได้ส่งสัญญาณไปยังกระบวนการพื้นหลังหลังจากที่ได้รับมันจากสถานีที่ปิดในหน้าของมัน ดูเหมือนกับว่าhuponexit
ไม่มีการแบกทางเดียวหรืออื่น ๆ
ฉันหวังว่าสิ่งนี้จะลบความลึกลับหรือความสับสนใด ๆ ที่เกี่ยวกับ huppiness ของ bash อย่างน้อยประมาณเวลาและวิธีการที่ส่งสัญญาณ HUP อย่างน้อยการทดสอบของฉันก็ทำซ้ำได้อย่างสมบูรณ์สำหรับฉัน ฉันสนใจที่จะทราบว่ามีการตั้งค่าอื่น ๆ ที่อาจมีผลต่อพฤติกรรมของทุบตี
และเช่นเคย YSMV (Your Shell May Vary)
ภาคผนวก 1
เมื่อฉันเรียกใช้เชลล์เป็น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