#!/bin/sh set -eu usage() { cat <<-'EOF' Usage: muffle [--] COMMAND... muffle -h EOF } help() { cat <<-'EOF' Options: -h, --help show this message COMMAND the COMMAND to be muffled Conditionally omit STDOUT and STDERR of COMMAND: if command exits with an error, print its original output to the corresponding streams, but when there is no error, throw the output away, "muffling" the COMMAND. Examples: Only print anything if the test fails: $ muffle sh tests/assert-makefile.sh EOF } for flag in "$@"; do case "$flag" in (--) break ;; (--help) usage help exit ;; (*) ;; esac done while getopts 'h' flag; do case "$flag" in (h) usage help exit ;; (*) usage >&2 exit 2 ;; esac done shift $((OPTIND - 1)) OUT="$(mkstemp)" ERR="$(mkstemp)" STATUS_F="$(mkstemp)" trap 'rm -f "$OUT" "$ERR" "$STATUS_F"' EXIT timed() { ts -s -m '%.s' } echo 0 > "$STATUS_F" { { "$@" || echo $? > "$STATUS_F"; } | timed | pre out > "$OUT" } 2>&1 | timed | pre err > "$ERR" STATUS="$(cat "$STATUS_F")" if [ "$STATUS" != 0 ]; then cat "$OUT" "$ERR" | sort -k2 | while read -r line; do if [ "$(echo "$line" | cut -d' ' -f1)" = 'out:' ]; then echo "$line" | cut -d' ' -f3- >&1 else echo "$line" | cut -d' ' -f3- >&2 fi done exit "$STATUS" fi