時々発生する141シェルスクリプトエラーのデバッグ

時々発生する141シェルスクリプトエラーのデバッグ

CI(Gitlab、Alpine Linuxを実行しているDockerコンテナ)でスクリプトを実行すると、信号141が「SIGPIPE」を意味するように見える散発的なエラーが発生しました。しかし、どのステップが失敗するのか、どのようにデバッグするのか理解できません。

  #!/usr/bin/env bash

  set -euxo pipefail
  set -a

  # ...
  git fetch --tags 

  RELEASE=$(git tag | grep -E "${BUILD_ENV}-release-(\d+)" | cut -d"-" -f3 | sort -nr | head -1)
  RELEASE=$(( RELEASE + 1 ))

パイプラインの最後の行から2番目の行内で散発的なエラーが発生しているようです。私が受け取ったログは次のとおりです。

++ git tag
++ cut -d- -f3
++ sort -nr
++ grep -E 'prod-release-(\d+)'
++ head -1
+ RELEASE=323
ERROR: Job failed: exit code 141

実際にどの行が失敗するのかを調べるためにこれをどのようにデバッグしますか? RELEASE変数を正常に埋めたように見えますが、まだ問題が発生していますか?

答え1

head -1操作が完了すると、すべてのsort -nrデータをパイプに書き込むことができるかどうかに関係なく終了します。sort書く内容があり、もはやheadなければそれで十分sortですSIGPIPE

何も爆発しません。これがパイプの動作方法です。パイプラインで使用する場合、前のheadコマンドがSIGPIPE


yes代わりに簡単なテストsort

$ set -o pipefail
$ yes | head -n 1
y
$ printf '%s\n' "$?" "${PIPESTATUS[@]}"
141             <- overall exit status
141             <- from `yes'
0               <- from `head'

終了状態はで141、ソースはですyes

デバッグ方法を示します${PIPESTATUS[@]}


この動作は予想されます。パイプラインのこの部分の終了状態を操作するには、代わりにyes(またはあなたの場合ではなく)subshel​​lを使用してください。sort例:

$ set -o pipefail
$ (yes; true) | head -n 1
y
$ printf '%s\n' "$?" "${PIPESTATUS[@]}"
0
0
0

より複雑なロジックのみを抑制します141

(yes; e="$?"; [ "$e" -eq 141 ] && exit 0; exit "$e") | head -n 1

関連情報