後台程序(postgresql)在 shell 中從 Ctrl-C 接收 SIGINT
我寫了一個
shell.nix
文件來為我的一個項目建構開發環境。我使用 ashellHook
來確保在您進入nix-shell
.
shellHook
本質上是:export PGDATA=$PWD/nix/pgdata pg_ctl start --silent --log $PWD/log/pg.log
儘管
pg_ctl
在後台啟動伺服器,但如果我在 shell 中鍵入 Ctrl-C,伺服器就會關閉。如果我在 nix-shell 之外設置相同的場景,則不會發生這種情況。我是 strace 的新手,但在我看來,
SIGINT
當我在終端中鍵入 Ctrl-C 時,postgresql 程序正在接收:$ strace -p $postgres_pid strace: Process 20546 attached select(6, [3 4 5], NULL, NULL, {tv_sec=51, tv_usec=289149}) = ? ERESTARTNOHAND (To be restarted if no handler) --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} --- rt_sigprocmask(SIG_SETMASK, ~[ILL TRAP ABRT BUS FPE SEGV CONT SYS RTMIN RT_1], NULL, 8) = 0 write(2, "LOG: received fast shutdown req"..., 37) = 37 kill(20550, SIGTERM) = 0 ...
postgresql 程序與我的 nix-shell 程序連接到同一個控制終端 (
pts/12
)(儘管當我在 nix-shell 之外執行它時也是如此):$ ps -p ${postgres_pid},${nixshell_pid} -o pid,ppid,wchan,tty,cmd PID PPID WCHAN TT CMD 14608 18292 core_s pts/12 bash --rcfile /tmp/nix-shell-14608-0/rc 16355 1 core_s pts/12 /nix/store/xxxxxx-postgresql-9.6.8/bin/postgres
調試這個好的下一步是什麼?我應該閱讀程序組嗎?
更新:嘗試另一個問題的提示,我發現這解決了問題:
set -m pg_ctl start --silent --log $PWD/log/pg.log
奇怪的是,根據
$-
,該m
選項已經設置。執行在.echo $-
_imBH``set -m
我注意到在我的互動式 shell(無論是否 nix-shell)中,
$-
是imBHs
. 上下文中s
不存在,我在 Bash內置shellHook
的文件中找不到其含義的解釋。set
雖然這可能不相關……
似乎問題在於 postgresql 伺服器與通過
pg_ctl
. 鍵入將 a 傳播SIGINT
到組中的所有程序。解決此問題的一種方法是使用
setsid
.setsid pg_ctl start --silent --log $PWD/log/pg.log
也就是說,我仍然不知道為什麼這只發生在
shellHook
.
手冊說
啟動模式啟動一個新伺服器。… 在類 Unix 系統上,預設情況下,伺服器的標準輸出和標準錯誤被發送到 pg_ctl 的標準輸出(不是標準錯誤)。然後 pg_ctl 的標準輸出應該被重定向到一個文件或通過管道傳送到另一個程序,例如像 rotatelogs 這樣的日誌輪換程序;否則postgres 會將其輸出寫入控制終端(從後台),並且不會離開 shell 的程序組。…建議使用 -l 或輸出重定向。
看來您需要重定向輸出以從外殼中分離 pg_ctl 。