4

I want to suppress errors in my sub-shell after a certain point.

I wrote script to demonstrate the situation:

worked=false
(echo Starting subshell process \
    && echo If this executes process is considered success \
    && false \
    && echo run if possible, but not an error if failed) \
  && worked=true

echo $worked

I want to report back to the outer shell that the process worked.

I also thought about putting the worked variable inside the subshell:

    && echo This works process worked: \
    && worked=true \
    && false \
    && echo run if possible, but not an error if failed)

But this doesn't work either because setting a variable inside the subshell doesn't effect the main script.

7

How about this

worked=false
(
    set -e
    echo Starting subshell process
    echo If this executes process is considered success
    false
    echo run if possible, but not an error if failed || true
)
[[ 0 -eq $? ]] && worked=true

echo "$worked"

The set -e terminates the subshell as soon as an unprotected error is found. The || true construct protects a statement that might fail, where you don't want the subshell to terminate.

If you just want to know if the subshell succeeded you can dispense with the $worked variable entirely

(
    set -e
    ...
)
if [[ 0 -eq $? ]]
then
    echo "Success"
fi

Note that if you want to use set -e to abort execution in the subshell as soon as a command fails, you cannot use a construct such as ( set -e; ... ) && worked=true or if ( set -e; ...); then ... fi. This is documented in the man page for bash but I missed it first time round:

If a compound command or shell function sets -e while executing in a context where -e is ignored, that setting will not have any effect until the compound command or the command containing the function call completes.

  • Does that set -e work for you there? Because I tried it, and it doesn't seem to work with (set -e ...) && something. This prints both foo and ok: bash -c '(set -e; false; echo foo) && echo ok' Same with dash, ksh and zsh, but if I change && to ; it works as I expected and outputs only ok – ilkkachu Dec 13 '17 at 22:23
  • Same-o with if (set -e; false; echo foo); then echo ok; fi. Though without the if or && it seems to set $? just fine... – ilkkachu Dec 13 '17 at 22:34
  • While I knew set -e does not affect commands that act as conditions (in if or before &&), having it totally ignored in the subshell too seems odd. It's not like triggering the error exit from the subshell would exit the outer shell, where the condition actually is... – ilkkachu Dec 14 '17 at 11:51
  • @ilkkachu likewise. I had to dig hard to find the behaviour you'd described - thank you again. – roaima Dec 14 '17 at 11:53
1
worked=false
(status=1;
    echo Starting subshell process \
    && echo If this executes process is considered success \
    && status=0
    && false \
    && echo run if possible, but not an error if failed;
    exit $status) \
  && worked=true

echo $worked
1

You could put the mandatory commands in the condition of an if, no need to connect everything with a && chain:

worked=false
(   if echo Starting subshell process &&
       echo If this executes process is considered success ; then
        false &&
        echo run if possible, but not an error if failed
        exit 0
    fi
    exit 1 ) && worked=true

echo worked=$worked
0

My solution was to create a variable inside the subshell and manually control the exit codes based on that:

worked=false
(echo Starting subshell process \
    && echo If this executes process is considered success \
    && check=true \
    && false \
    && echo run if possible, but not an error if failed
  if [[ -n "$check" ]]; then exit 0; else exit 1; fi) \
  && worked=true

echo $worked
  • an alternate way to use the variable would be to save the error code in it directly and exit with that code directly, e.g. ret=1; important command && ret=0 && non-important command; exit $ret – ilkkachu Dec 14 '17 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.