The first version of our real Docker installation script stopped with exit code 141 even though Docker package operations were healthy. Docker Engine was not the root cause: set -o pipefail was enabled and the display-only pipeline 'apt-cache policy docker-ce | head -n 20' caused the upstream command to receive SIGPIPE when head exited early. Replacing it with sed -n allowed the script to continue; the final environment verified Docker 29.7.2 and Compose v5.4.0.
set -o pipefail
apt-cache policy docker-ce | head -n 20
↓
head exits early
upstream gets SIGPIPE
128 + SIGPIPE(13) = exit 141
↓
apt-cache policy docker-ce | sed -n '1,20p'
↓
script continuesAfter package installation the script shortened apt-cache policy output with head. With pipefail enabled, the upstream SIGPIPE status made the whole pipeline fail.
So exit 141 did not mean Docker itself failed.
set -o pipefailapt-cache policy docker-ce | head -n 20echo $?Shells commonly report signal termination as 128 plus the signal number. SIGPIPE is signal 13, so 128 + 13 gives 141.
head closes the pipe after enough lines; an upstream writer may then receive SIGPIPE.
Without pipefail, a pipeline often reports the last command's status. With pipefail, a failing upstream command affects the pipeline status.
Combined with set -e, this can terminate the whole script.
set -euo pipefailapt-cache policy can produce more output than head consumes. Once head has 20 lines, it closes its side of the pipe and the producer can get SIGPIPE.
This is a pipeline-lifecycle issue, not a package-data problem.
apt-cache policy docker-ce | head -n 20We replaced the display line with apt-cache policy docker-ce | sed -n '1,20p'. sed can consume the input stream while printing only the requested lines, avoiding the early closed pipe.
This preserved pipefail without the accidental SIGPIPE.
apt-cache policy docker-ce | sed -n '1,20p'After exit 141, docker --version, docker compose version, service status and hello-world reveal the actual Docker state.
Our real final screen verified Docker 29.7.2 and Compose v5.4.0.
docker --versiondocker compose versionsystemctl is-active dockerdocker run --rm hello-worldSeparate informational output from critical installation steps. Do not let a cosmetic pipeline use the same failure policy as package installation.
Use targeted fallbacks when justified, but do not hide real apt/docker failures with blanket || true.
After the fix, Docker Engine, Compose and Portainer were verified in real screens. That supports the conclusion that Bash pipeline handling—not Docker Engine—was the root cause.
For similar exit 141 failures, identify the last pipeline executed.
In this case it represents SIGPIPE: 128 + signal 13.
No; the real final checks showed Docker was installed and working.
apt-cache policy docker-ce | head -n 20.
It propagates upstream failures into the pipeline status.
The script can terminate when the pipeline returns non-zero.
It closes the pipe after receiving the requested lines.
Replace head with sed -n '1,20p'.
Not blindly; it can hide real failures.
Version, Compose, service status and hello-world.
No; any pipeline scenario producing SIGPIPE can yield it.
It can keep consuming input while printing selected lines.
The pipeline executed immediately before exit 141.
Yes; verify apt update and real package-install results separately.
Yes, the same pattern can occur in non-interactive Bash with pipefail.
Run Docker and self-hosted services on EKA Sunucu Linux VPS.
Updated: 10.08.2026