🐜

Javaからシェルを呼び出したら終了ステータスが141だったので調査した

2024/08/01に公開

おはこんばんにちわ
狸です

今日も20年以上前に作られた古代の遺物をどうにかして修正して動かすみたいな仕事しています。

今回の内容はタイトル通りです

調べることになった発端

ソースの作成者も設計書も今は亡きソースを改修してるときに以下のようなコードを見つけました

ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
~なんかやたら冗長なコード~
int exitCode = process.waitFor();
if (exitCode == 141) {
 // よくわからないけど正常終了するのでヨシ!
}

こんなコード…

マジで〇ねよと思いましたが作った人がいないんだからこの殺意のやり場もなく今回手を入れる箇所なのでムカムカしながら調べました

答え合わせ

いきなりですが答えはbashのマニュアルに載っています

https://ja.manpages.org/bash

ここに以下のような記述があります

今回の場合は141-128=13なので
https://ja.manpages.org/signal/7
を確認するとSIGPIPEでコマンドが落ちてる感じですね

$ tail -f /dev/null | head -n0

みたいなコマンド実行するとtailがまだ出してるのにhead終わっちゃってるからパイプ壊れちゃった~ってtailコマンド側が出すステータスです。

今回はJava側で標準出力から欲しい出力取得したらさっさとストリーム閉じる実装になってたのでそこで発生してました。

なのでwaitForでプロセス終了してから閉じる実装にすれば治りましたとさ

とっぴんぱらりのぷう

P.S

てかこれの悪質な所は標準出力閉じるタイミングとコマンドの終了するタイミングがほぼ同時位だからこのエラーが出たりでなかったりする所なんだよなぁ

他にもsleep入れたら何故か動いたみたいな阿保みたいなコードとかも大量にあるしホンマ作ったやつの爪と肉の間に釘打ち込みたい

Discussion