Sample Header Ad - 728x90

Inconsistent “unzip -l … | grep -q …” results with pipefail

13 votes
3 answers
970 views
The following Bash function gave inconsistent results:
# $1    Path to ZIP archive.
# Exits with 0 status iff it contains a “.mp3” or “.flac” file.
mp3_or_flac_in_zip() {
    local archive=${1:?No archive given.}
    (
        set -o pipefail
        unzip -l "$archive" | grep -iqE '.\.(flac|mp3)$'
    )
}
When run _n_ times in a row on the same music-containing ZIP, it randomly reported that there was no music in it (about 1–5 % of the time, but it varied greatly across ZIPs). Switching to **an intermediate variable instead of a pipe** (with && instead of set -o pipefail to still make sure unzip was running fine) fixed the inconsistencies:
# $1    Path to ZIP archive.
# Exits with 0 status iff it contains a “.mp3” or “.flac” file.
mp3_or_flac_in_zip() {
    local archive=${1:?No archive given.}
    local listing
    listing=$(unzip -l "$archive") &&
    grep -iqE '.\.(flac|mp3)$' <<< "$listing"
}
What could be the issue, there? And are there other contexts where pipes are not such a good idea?
Asked by Alice M. (389 rep)
Aug 25, 2024, 02:51 PM
Last activity: Aug 26, 2024, 05:42 AM