bash: Piped commands might randomly be executed out of order
There is a strange issue with the Alpine docker images, issue that couldn't be reproduced in ubuntu 16.04, 18.04, or even ubuntu:18.04
docker image.
Basically, it seems that Alpine bash
doesn't always execute the commands in a pipe in the same order every time. For example, running this script [1] a few times, it would yield the following output:
bash-5.0# ./exec.sh
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Passed: 199, Failed: 1
bash-5.0# ./exec.sh
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Passed: 193, Failed: 7
bash-5.0# ./exec.sh
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Passed: 199, Failed: 1
bash-5.0# ./exec.sh
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Passed: 198, Failed: 2
bash-5.0# ./exec.sh
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Passed: 197, Failed: 3
bash-5.0# ./exec.sh
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
Passed: 198, Failed: 2
The failure count is about 1-8 out of 200. It's even worse when running with the -x
option, the failure count increases to about 4-25 out of 200. But running with the -x
option and looking at the generated logs, the following could be observed:
+ for i in {1..200}
+ ensure-gnu-sed
+ LANG=C
+ sed --help
+ grep -q 'GNU\|BusyBox'
+ passed=3
+ for i in {1..200}
+ ensure-gnu-sed
+ LANG=C
+ grep -q 'GNU\|BusyBox'
+ sed --help
+ command -v gsed
+ echo 'Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.'
Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed.
+ failed=1
As you can see in the failure case, grep
has been executed before sed --help
, even though the command is if LANG=C sed --help 2>&1 | grep -q "GNU\|BusyBox"; then
. This will lead to a false evaluation, which is undesired.
Changing the script to instead execute:
sed_help="$(LANG=C sed --help 2>&1)"
if echo "${sed_help}" | grep -q "GNU\|BusyBox"; then
will reduce the failure count to 0.
[1] https://paste.ubuntu.com/p/q4c2J3GM9j/
Issue was tested on alpine 3.11 and 3.10:
bash-5.0# cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.11.3
PRETTY_NAME="Alpine Linux v3.11"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"