我写了一个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
虽然这可能不相关......
手册说
看来您需要重定向输出以从外壳中分离 pg_ctl 。
似乎问题在于 postgresql 服务器与通过
pg_ctl
. 键入将 a 传播SIGINT
到组中的所有进程。解决此问题的一种方法是使用
setsid
.也就是说,我仍然不知道为什么这只发生在
shellHook
.