我有一个类似的问题,但首先,我会给你一些提示来调试你的问题:
查看您的流程层次结构以了解是否存在不应该存在的流程。ps faux
如果一个进程挂在某个东西上,而您不知道是什么,您可以strace -p <PID>
查看阻塞该进程的系统调用
如果这是关于文件描述符(在读取或写入调用时阻塞),那么您可以使用查看该进程的文件描述符lsof -p <PID>
现在,如果您想查看其他进程正在使用此文件描述符,您可以查看NODE
列上的数字并运行:lsof | grep <NODE>
我遇到的问题是钩子脚本的标准输出和标准错误被 git 捕获在管道中,以将它们转发到远程主机(执行 git push 的主机)。此外,我的脚本重新启动了 postgresql 守护进程。因此,postgresql 继承了 git 的标准输出和标准错误。也就是说,将所有内容转发回远程命中主机的管道。
一种解决方案是在生成服务时关闭 stdout 和 stderr,例如:
service postgresql restart >&- 2>&- <&-
但是,您不会收到任何错误消息。我犯规的另一个更通用的解决方案是将以下代码放入我的更新后挂钩中:
# Creates a temp file
t="$(tempfile)" || exit
trap "rm -f -- '$t'" EXIT
# Run the script
# You need to run the script in background, and to redirect its standard and
# error output to $t
bash path/to/script.bash >"$t" 2>&1 </dev/null &
# use tail -f to follow the output of the script, and --pid to exit when the
# previous script exits ($! is the pid of the script). This might not be very
# portable though
tail -n 0 --pid $! -f "$t"
# Clean up temp file
# if a process is still attached to it, the inode won't be cleared until the
# process close the file or dies. In our case, we don't care much.
rm -f -- "$t"
trap - EXIT