Depuración de errores esporádicos del script de shell 141

Depuración de errores esporádicos del script de shell 141

Mientras ejecuto un script en CI (Gitlab, contenedor Docker que ejecuta Alpine Linux), obtengo fallas esporádicas con la señal 141 que parece indicar un "SIGPIPE". Pero no entiendo qué paso falla ni qué hacer para depurarlo.

  #!/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 ))

El error esporádico parece ocurrir dentro de la tubería en la penúltima línea, el registro que obtengo es:

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

¿Cómo haría para depurar esto para descubrir qué línea realmente falló? ¿Parece que la variable RELEASE se completó correctamente pero de alguna manera explotó?

Respuesta1

Después de head -1hacer su trabajo, sale independientemente de si sort -nrlogró escribir todos los datos en la tubería. Si sorttiene algo más que escribir y headya no existe, lo sortconseguiré SIGPIPE.

Nada explota. Así funcionan las tuberías. Cuando utilice headen una tubería, no debería sorprenderse si el comando anterior sale debido a SIGPIPE.


Prueba simple con yesen lugar de sort:

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

El estado de salida es 141y viene de yes.

Esto muestra cómo depurar: examinando ${PIPESTATUS[@]}.


El comportamiento es esperado. Utilice una subcapa en lugar de yes(o en su caso en lugar de sort) para manipular el estado de salida de esta parte de la tubería. Ejemplo:

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

Lógica más compleja para suprimir únicamente 141:

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

información relacionada