GNU/Linux >> Belajar Linux >  >> Linux

Apakah proses latar belakang mendapatkan SIGHUP saat log off?

Solusi 1:

Jawaban ditemukan.

Untuk BASH, ini tergantung pada huponexit opsi shell, yang dapat dilihat dan/atau disetel menggunakan shopt bawaan perintah.

Sepertinya opsi ini dinonaktifkan secara default, setidaknya pada sistem berbasis RedHat.

Info lebih lanjut di halaman manual BASH:

Shell keluar secara default setelah menerima SIGHUP. Sebelum keluar, shell interaktif mengirim ulang SIGHUP ke semua pekerjaan, berjalan atau berhenti. Pekerjaan yang dihentikan dikirim SIGCONT untuk memastikan bahwa mereka menerima SIGHUP. Untuk mencegah shell mengirimkan sinyal ke pekerjaan tertentu, itu harus dihapus dari tabel pekerjaan dengan disown bawaan (lihat PERINTAH BUILTIN SHELL di bawah) atau ditandai untuk tidak menerima SIGHUP menggunakan disown -h.

Jika opsi shell huponexit telah disetel dengan shopt, bash mengirimkan SIGHUP ke semua pekerjaan saat shell login interaktif keluar.

Solusi 2:

Itu akan dikirim SIGHUP dalam pengujian saya:

Shell1:

[[email protected]: ~] ssh localhost
[[email protected]: ~] perl -e sleep & 
[1] 1121
[[email protected]: ~] 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

Shell1 Lagi:

[[email protected]: ~] exit
zsh: you have running jobs.
[[email protected]: ~] exit
zsh: warning: 1 jobs SIGHUPed
Connection to localhost closed.

Shell2 Lagi :

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

Mengapa masih berjalan?:
Pemrograman Tingkat Lanjut di Lingkungan Unix oleh Stevens membahas hal ini di bawah bagian 9.10:Grup Proses Yatim Piatu. Bagian yang paling relevan adalah:

Karena grup proses menjadi yatim piatu saat induknya berhenti, POSIX.1 mengharuskan setiap proses dalam grup proses yatim piatu yang baru dihentikan (sebagai anak kita) dikirimi sinyal hang-up (SIGHUP) diikuti oleh sinyal lanjutkan (SIGCONT).

Hal ini menyebabkan anak dilanjutkan, setelah memproses sinyal hang-up. Tindakan default untuk sinyal hang-up adalah menghentikan proses, jadi kita harus menyediakan penangan sinyal untuk menangkap sinyal. Oleh karena itu, kami berharap printf dalam fungsi sig_hup muncul sebelum printf dalam fungsi pr_ids.

Solusi 3:

Saya menjalankan beberapa tes menggunakan CentOS 7.1 dan bash. Perhatikan ini berarti huponexit adalah off secara default, dan nonaktif untuk sebagian besar pengujian saya.

Anda membutuhkan 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 mengetikkan exit atau tekan Control-D pada prompt perintah - tidak ada sinyal apa pun yang dikirim ke tugas latar belakang dari bash.

Tes:

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 +++

Tugas 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 putaran:

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
...

Keluaran di Terminal 3:

Terminal 3

out 1
out 2
out 3
HUP
out 4
out 5
out 6

Namun, jika Anda keluar dari bash , itu keluar begitu saja tanpa mengirimkan sinyal apa pun kepada anak sama sekali. Terminal akan keluar karena tidak lagi memiliki anak, tetapi tentu saja tidak ada yang HUP karena cangkang anak sudah hilang. SIGINT , SIG_BLOCK dan SIG_SETMASK Anda lihat di bawah ini disebabkan oleh sleep di dalam cangkang.

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 menyetel huponexit untuk menggunakan shopt -s huponexit; shopt (yang terakhir berbelanja untuk meninjau), kemudian melakukan tes terakhir, dan sekali lagi bash tidak mengirim sinyal ke proses latar belakang . Bahkan LEBIH menarik, seperti yang telah kita lihat bash lakukan mengirim sinyal ke proses latar belakang setelah menerimanya dari terminal yang tertutup di wajahnya. Sepertinya huponexit tidak ada hubungannya.

Saya harap ini menghilangkan misteri atau kebingungan tentang setidaknya bash's huppiness, tentang kapan dan bagaimana sinyal HUP dikirim. Setidaknya tes saya dapat direproduksi sepenuhnya, bagi saya. Saya akan tertarik untuk mengetahui apakah ada pengaturan lain yang mungkin memengaruhi perilaku bash.

Dan, seperti biasa, YSMV (Cangkang Anda Dapat Bervariasi).

Tambahan 1

Saat saya menjalankan shell sebagai exec /bin/sh , lalu jalankan skrip sebagai /bin/sh ./doit.sh & , lalu keluar dari shell dengan bersih, tidak ada sinyal yang dikirim ke tugas latar belakang dan terus berjalan hingga selesai.

Tambahan 2

Saat saya menjalankan shell sebagai exec /bin/csh , lalu jalankan skrip sebagai /bin/sh ./doit.sh & , lalu keluar dari shell dengan bersih, tidak ada sinyal yang dikirim ke tugas latar belakang dan terus berjalan hingga selesai.


Linux
  1. Mengapa Saya Dapat Melihat Output Dari Proses Latar Belakang?

  2. Commandline menimpa dirinya sendiri ketika perintah terlalu panjang

  3. Bagaimana cara mematikan semua proses latar belakang di zsh?

  1. Bagaimana cara mendapatkan errno saat epoll_wait mengembalikan EPOLLERR?

  2. Mengapa LXC ketika ada linux-vserver?

  3. Dapatkan rata-rata beban tidak termasuk proses yang bagus

  1. Saya mendapatkan error 404 saat mengakses cPanel

  2. Bagaimana cara mendapatkan ID proses dari proses latar belakang?

  3. Apakah proses tidur mendapatkan waktu CPU yang sama?