git hookスクリプトでstdinがブロックする問題をTTY判定で回避する
lefthookからシェルスクリプトを呼び出したとき、cat や read でstdinを読もうとするとスクリプトがハングする問題があった。Codex(OpenAI)に修正を任せたらサクッと直してくれた。
原因:
lefthookはスクリプトのstdinをパイプで接続する。ターミナルから直接実行した場合はstdinにユーザー入力が来るが、lefthook経由だとパイプの先に何もないので cat がEOFを待ち続けてブロックする。
解決:
# stdinがTTY(ターミナル)かパイプかを判定
if [ -t 0 ]; then
# ターミナルから直接実行 → stdinを読める
FILES=$(cat)
else
# パイプ経由(lefthookなど) → stdinを読まずにfallback
FILES=$(git diff --cached --name-only)
fi
調査の勘所:
[ -t 0 ]はファイルディスクリプタ0(stdin)がターミナルに接続されているかを判定するPOSIXの方法- git hookスクリプトはターミナル直接実行とhookマネージャ経由の両方で動くことを想定して、stdin以外のfallback(
git diff --cached等)を用意しておくとよい - この手のシェルスクリプトの環境依存バグは、AIエージェントに任せると原因特定から修正まで速い