error-handlingshio-redirectionsubshell

Console output from subshell ONLY on failure


I have complex multi-step 'init' operations which can be ignored when they work. Having the echoed commands and their output at the beginning of every operation swamps the output you care about.

I want to be able to have them effectively silent if they work, but get the benefit of normal console output in the case that they fail for whatever (rare) reason.

My attempt to do this tersely in sh as below simply hangs for the cases of commands I've tried.

Note I have kept individual commands separate rather than chaining with && otherwise you don't get an echo of each command individually. E.g. in a set of 10 commands this makes it nearly impossible to know which command ran to cause the error. Using && varies the console input you would expect from the series of commands and creates a new black box problem.

export LOG=$(mktemp)
(
    > $LOG 2>&1
    set -e
    command1
    command2
) || { cat $LOG; exit 1; } 

Is there a correct way to execute this approach - to direct echoed commands and stream output from the subshell to a temporary location and either...

Update: Following on from the accepted answer, I ended up proving the approach with a working example in sh (where commands like true and false are intended to emulate succeeding and failing commands) like this.

LOG=$(mktemp)
( 
  set -o errexit -o nounset -o pipefail -o xtrace
  false || (echo "First command errored" >&2 && false) 
  true || (echo "Second command errored" >&2 && false) 
) >$LOG 2>&1
[ $? -eq 0 ] || { cat $LOG;}

Solution

  • This should work:

    ( set -e; command1; command2 ) >$LOG 2>&1
    test $? -eq 0 || { cat $LOG;}