Skip to content

Instantly share code, notes, and snippets.

@stbuehler
Created July 12, 2015 09:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stbuehler/15fe5152dea15fffadc7 to your computer and use it in GitHub Desktop.
Save stbuehler/15fe5152dea15fffadc7 to your computer and use it in GitHub Desktop.
Capture stdout/stderr of a command while keeping the exit code
#!/bin/bash
syntax() {
echo "$0 [options] [--] cmd..."
echo "Options:"
echo " --stdout <logfile>: append stdout to logfile"
echo " --stderr <logfile>: append stderr to logfile"
echo "Returns exit code returned by captured command"
exit 1
}
capture_stdout=
capture_stderr=
if [ $# = 0 ]; then
syntax
fi
while [ $# -gt 0 ]; do
case "$1" in
--stdout=*)
capture_stdout="${1#--stdout=}"
shift
;;
--stdout)
capture_stdout="$2"
shift 2
;;
--stderr=*)
capture_stderr="${1#--stderr=}"
shift
;;
--stderr)
capture_stderr="$2"
shift 2
;;
-h|--help|"-?")
syntax
;;
--)
shift
break
;;
-*)
echo >&2 "Unknow argument: $1"
syntax
;;
*)
break
;;
esac
done
if [ $# = 0 ]; then
echo >&2 "Missing command to execute and capture output from"
syntax
fi
if [ -z "${capture_stdout}" -a -z "${capture_stderr}" ]; then
echo >&2 "Not capturing any output"
syntax
fi
if [ -n "${capture_stdout}" ]; then
exec 3>&1 >&-
coproc stdout {
exec tee -a "${capture_stdout}" >&3
}
fd0=${stdout[0]}
fd1=${stdout[1]}
exec {fd0}>&- >&${fd1} {fd1}>&-
fi
if [ -n "${capture_stderr}" ]; then
exec 4>&2 2>&-
coproc stderr {
exec tee -a "${capture_stderr}" >&4 2>&4
}
fd0=${stderr[0]}
fd1=${stderr[1]}
exec {fd0}>&- 2>&${fd1} {fd1}>&-
fi
"$@"
rc=$? 3>&- 4>&-
if [ -n "${capture_stdout}" ]; then
exec >&3 3>&-
wait "${stdout_PID}"
fi
if [ -n "${capture_stderr}" ]; then
exec 2>&4 4>&-
wait "${stderr_PID}"
fi
exit "${rc}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment