同様の問題がありますが、最初に、問題をデバッグするためのヒントを示します。
プロセス階層を調べて、そこにあるべきではないプロセスがあるかどうかを確認します。ps faux
プロセスが何かにぶら下がっているままで、何がわからない場合はstrace -p <PID>
、プロセスをブロックしているシステムコールを確認できます。
これがファイル記述子(読み取りまたは書き込み呼び出しでのブロック)に関するものである場合は、を使用してそのプロセスのファイル記述子を確認できます。lsof -p <PID>
ここで、このファイル記述子を使用している他のプロセスを確認したい場合は、NODE
列の番号を確認して実行できます。lsof | grep <NODE>
私が抱えていた問題は、フックスクリプトからの標準出力と標準エラーがパイプ内のgitによってトラップされ、リモートホスト(gitプッシュを実行したホスト)に転送されることでした。また、私のスクリプトはpostgresqlデーモンを再起動しました。結果として、postgresqlはgitから標準出力と標準エラーを継承しました。つまり、すべてをリモートヒットホストに転送するパイプです。
1つの解決策は、サービスを生成する場合にstdoutとstderrを閉じることです。たとえば、次のようにします。
service postgresql restart >&- 2>&- <&-
ただし、エラーメッセージは表示されません。私が考えたもう1つのより一般的な解決策は、更新後のフックに次のコードを配置することでした。
# 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