Archive for July, 2018

Bash -o pipefail can have pitfails^Wpitfalls

July 23, 2018

Using `-o pipefail` is generally a good idea. However it can contain some surprises. For example the following shell script:

#!/bin/bash
set -e
set -o pipefail

output="$(cat /etc/passwd)"
for i in $(seq 100000); do
    echo "$output" | grep -q "^root" || res=$?
    if [ -n "$res" ]; then
        echo "failed: $i $res"
        exit 1
    fi
done
echo "done"

Does fail at different points in the loop. Why? Because grep is greedy and will exit as soon as it found a pattern. If the echo in the pipe did not finish writing to the pipe it will get a SIGPIPE when it tries to write the remaining data.

A better pattern is:

   grep -q -E "^root" <<< "$output"

Note that “-o pipefail” is already a bashism so adding “<<<" (which is also a bashism) does not make things worse 🙂

Advertisements