Supress errors in a subshell?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












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.







share|improve this question
























    up vote
    2
    down vote

    favorite












    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.







    share|improve this question






















      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      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.







      share|improve this question












      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.









      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 13 '17 at 21:54









      Philip Kirkbride

      2,2922370




      2,2922370




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          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.







          share|improve this answer






















          • 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

















          up vote
          1
          down vote













          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





          share|improve this answer



























            up vote
            1
            down vote













            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





            share|improve this answer





























              up vote
              0
              down vote













              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





              share|improve this answer






















              • 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







              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "106"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f410750%2fsupress-errors-in-a-subshell%23new-answer', 'question_page');

              );

              Post as a guest






























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              5
              down vote



              accepted










              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.







              share|improve this answer






















              • 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














              up vote
              5
              down vote



              accepted










              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.







              share|improve this answer






















              • 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












              up vote
              5
              down vote



              accepted







              up vote
              5
              down vote



              accepted






              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.







              share|improve this answer














              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.








              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 14 '17 at 10:14

























              answered Dec 13 '17 at 22:09









              roaima

              39.8k546109




              39.8k546109











              • 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
















              • 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















              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





              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




              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




              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




              @ilkkachu likewise. I had to dig hard to find the behaviour you'd described - thank you again.
              – roaima
              Dec 14 '17 at 11:53












              up vote
              1
              down vote













              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





              share|improve this answer
























                up vote
                1
                down vote













                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





                share|improve this answer






















                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  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





                  share|improve this answer












                  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






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 13 '17 at 22:20









                  Bruce

                  59136




                  59136




















                      up vote
                      1
                      down vote













                      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





                      share|improve this answer


























                        up vote
                        1
                        down vote













                        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





                        share|improve this answer
























                          up vote
                          1
                          down vote










                          up vote
                          1
                          down vote









                          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





                          share|improve this answer














                          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






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Dec 13 '17 at 22:30

























                          answered Dec 13 '17 at 22:16









                          ilkkachu

                          49.9k674137




                          49.9k674137




















                              up vote
                              0
                              down vote













                              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





                              share|improve this answer






















                              • 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














                              up vote
                              0
                              down vote













                              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





                              share|improve this answer






















                              • 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












                              up vote
                              0
                              down vote










                              up vote
                              0
                              down vote









                              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





                              share|improve this answer














                              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






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Dec 13 '17 at 22:25

























                              answered Dec 13 '17 at 22:12









                              Philip Kirkbride

                              2,2922370




                              2,2922370











                              • 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
















                              • 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















                              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




                              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












                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f410750%2fsupress-errors-in-a-subshell%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              How to check contact read email or not when send email to Individual?

                              Bahrain

                              Postfix configuration issue with fips on centos 7; mailgun relay