web-dev-qa-db-ja.com

bashでSIGPIPEを抑制する方法は?

次のコードを実行しようとしています:

set -euxo pipefail
yes phrase | make installer

Makefileはstdinのphraseを使用してインストーラーファイルを作成します。ただし、このコマンドはエラーコード141で終了し、CIビルドが壊れます。この例は、次のように簡略化できます。

yes | tee >(echo yo)

ここから何が見えるか: パイプの出力をT型に配管するときにパイプの失敗(141)-理由? -このエラーは、パイプの消費者が出力の消費を停止したことを意味します-これは私の場合は問題ありません。

パイプエラーを抑制し、make installerから戻りコードを取得する方法はありますか?

5
carbolymer

141の終了コードは、プロセスがSIGPIPEで失敗したことを示しています。これは、パイプが閉じるときにyesに発生します。これをCIに対してマスクするには、次のようなものを使用してエラーをマスクする必要があります

(yes phrase ||:) | make installer

これはyes phraseを実行し、失敗した場合はコード0で終了する:を実行します。yesは、書く。

これらのようなパイプの問題をデバッグするには、PIPESTATUSを確認するのが最善の方法です。

yes phrase | make installer || echo ${PIPESTATUS[@]}

これにより、障害時にパイプのすべての部分の終了コードが表示されます。終了コード141で失敗するものは、適切に処理できます。特定のエラーコードの一般的な処理パターンは次のとおりです。

(command; ec=$?; if [ "$ec" -eq 141 ]; then exit 0; else exit "$ec"; fi)

(ありがとう Hauke Laging );これはcommandを実行し、commandが成功した場合、またはコード141で終了した場合、コード0で終了します。他の終了コードはそのまま反映されます。

7
Stephen Kitt
( yes phrase ; exit 0 ) | make installer
1
Hauke Laging