Linux

為什麼關閉終端仿真器視窗會終止 SIGHUP 陷阱更改為不終止的 bash 程序?

  • March 4, 2020

在 lxterminal 的終端仿真器視窗中的 bash shell 中,我執行

$ trap "echo hello" SIGHUP 
$ kill -s HUP $$
hello
$

然後我關閉終端模擬器視窗。

關閉終端仿真器視窗是否只會導致 SIGHUP 發送到控制程序,即 bash 程序?

由於 SIGHUP 陷阱不會終止 bash 程序,我希望 bash 程序不會終止,但為什麼 bash 程序實際上會終止?

""如果我將陷阱更改為(忽略),也會發生同樣的事情。

終端仿真器很重要。在 xterm 視窗中執行的 bash 中,將 trap 設置為""將使 xterm 視窗無法關閉,而將 trap 設置為echo hello仍然可以關閉 xterm 視窗。

謝謝。

[我將忽略不同終端仿真器的實際和可能行為;一個完全合理的行為是在視窗關閉 / 時向 pty發送^D( ) ,而不是將其拆下並導致在其中執行的程序接收一個; 以下假設,在這種情況下,它將向shell 的程序組發送一個 ]。VEOF``WM_DELETE_WINDOW``SIGHUPxtermSIGHUP

您看到的行為是因為readline庫正在安裝自己的信號處理程序。如果您嘗試以下操作:

xterm -e bash --noediting

(或dashzshksh代替bash --noediting),然後執行

trap 'echo HUP' HUP

在終端中,視窗將無法關閉;HUP在嘗試關閉視窗時,shell 將按預期列印;強行關閉它(例如 with xkill)將導致 shell 退出並EIO出現錯誤,這是完全可以預料的,因為 pty 已被拆除。

這是您正在觀察的行為的更簡單的測試案例,不涉及終端仿真器。在終端中執行以下命令:

bash --rcfile <(echo 'trap "echo HUP" HUP')

然後kill -HUP $$只會 print HUP,但是(sleep 1; kill -HUP $$) &(或kill -HUP <pid>從另一個視窗)會導致 shell 列印exit並退出,除非你用--noediting(= 不要使用 readline)

被呼叫的readline()函式bash將在等待使用者輸入時安裝自己的信號處理程序,並在返回時恢復原始處理程序;SIGHUP等待使用者輸入的一段時間將導致它返回,這將被(在函式中)NULL視為,然後才有機會執行延遲的陷阱處理程序。EOF``bashyy_readline_get()

引用自:https://unix.stackexchange.com/questions/491626