Capture non-zero exit code from named pipe












2















The following toy script (tmp.sh) exits with code 0 even if the process sent to the named pipe fails. How can I capture the non-zero exit code from the named pipe? Or more in general, the fact that something has gone wrong?



#!/bin/bash

set -eo pipefail

mkfifo mypipe
FOOBAR > mypipe &

cat mypipe




Run and check exit code:



bash tmp.sh
tmp.sh: line 6: FOOBAR: command not found

echo $? # <- Exit code is 0 despite the "command not found"!









share|improve this question



























    2















    The following toy script (tmp.sh) exits with code 0 even if the process sent to the named pipe fails. How can I capture the non-zero exit code from the named pipe? Or more in general, the fact that something has gone wrong?



    #!/bin/bash

    set -eo pipefail

    mkfifo mypipe
    FOOBAR > mypipe &

    cat mypipe




    Run and check exit code:



    bash tmp.sh
    tmp.sh: line 6: FOOBAR: command not found

    echo $? # <- Exit code is 0 despite the "command not found"!









    share|improve this question

























      2












      2








      2








      The following toy script (tmp.sh) exits with code 0 even if the process sent to the named pipe fails. How can I capture the non-zero exit code from the named pipe? Or more in general, the fact that something has gone wrong?



      #!/bin/bash

      set -eo pipefail

      mkfifo mypipe
      FOOBAR > mypipe &

      cat mypipe




      Run and check exit code:



      bash tmp.sh
      tmp.sh: line 6: FOOBAR: command not found

      echo $? # <- Exit code is 0 despite the "command not found"!









      share|improve this question














      The following toy script (tmp.sh) exits with code 0 even if the process sent to the named pipe fails. How can I capture the non-zero exit code from the named pipe? Or more in general, the fact that something has gone wrong?



      #!/bin/bash

      set -eo pipefail

      mkfifo mypipe
      FOOBAR > mypipe &

      cat mypipe




      Run and check exit code:



      bash tmp.sh
      tmp.sh: line 6: FOOBAR: command not found

      echo $? # <- Exit code is 0 despite the "command not found"!






      bash named-pipes exit-code






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 17:02









      darioberdariober

      9661121




      9661121
























          2 Answers
          2






          active

          oldest

          votes


















          5














          You need to capture process id of background process and wait for it to set the correct exit status:



          #!/bin/bash
          set -eo pipefail

          rm -f mypipe
          mkfifo mypipe

          FOOBAR > mypipe &
          # store process id of above process into pid
          pid=$!

          cat mypipe

          # wait for background process to complete
          wait $pid


          Now when you run it:



          bash tmp.sh
          tmp.sh: line 6: FOOBAR: command not found
          echo $?
          127





          share|improve this answer
























          • You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

            – Paul Hodges
            Nov 23 '18 at 18:42











          • If wait is last commend as shown then exit status will be whatever returned by wait

            – anubhava
            Nov 24 '18 at 2:23











          • Which is the logical compliment to what I said, lol ;)

            – Paul Hodges
            Nov 26 '18 at 13:58



















          1














          If you need to be able to catch errors and apply specific behavior, a trap can be your friend. This code prints itself, so I just post a run here:



          $: tst
          + trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
          + rm -f mypipe
          + mkfifo mypipe
          + pid=6404
          + cat mypipe
          + cat ./tst
          #! /bin/env bash

          set -x

          trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
          #set -eo pipefail

          rm -f mypipe
          mkfifo mypipe

          cat $0 >mypipe &
          pid=$!
          cat mypipe
          wait $pid

          fubar >mypipe &
          pid=$!
          cat mypipe
          wait $pid

          echo done

          + wait 6404
          + pid=7884
          + cat mypipe
          + fubar
          ./tst: line 16: fubar: command not found
          + wait 7884
          ++ x=127
          ++ echo 127@./tst:19
          127@./tst:19


          Note the trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err line.
          It sets x to the last error code, which will be whatever triggered it. Then it prints the code, the filename, and the line number it is currently executing (before the trap) and exits the program with the error code. This actually triggers on the wait. It causes it to bail before continuing the echo at the bottom.



          It works with or without the set -eo pipefail.






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            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',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53450561%2fcapture-non-zero-exit-code-from-named-pipe%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            5














            You need to capture process id of background process and wait for it to set the correct exit status:



            #!/bin/bash
            set -eo pipefail

            rm -f mypipe
            mkfifo mypipe

            FOOBAR > mypipe &
            # store process id of above process into pid
            pid=$!

            cat mypipe

            # wait for background process to complete
            wait $pid


            Now when you run it:



            bash tmp.sh
            tmp.sh: line 6: FOOBAR: command not found
            echo $?
            127





            share|improve this answer
























            • You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

              – Paul Hodges
              Nov 23 '18 at 18:42











            • If wait is last commend as shown then exit status will be whatever returned by wait

              – anubhava
              Nov 24 '18 at 2:23











            • Which is the logical compliment to what I said, lol ;)

              – Paul Hodges
              Nov 26 '18 at 13:58
















            5














            You need to capture process id of background process and wait for it to set the correct exit status:



            #!/bin/bash
            set -eo pipefail

            rm -f mypipe
            mkfifo mypipe

            FOOBAR > mypipe &
            # store process id of above process into pid
            pid=$!

            cat mypipe

            # wait for background process to complete
            wait $pid


            Now when you run it:



            bash tmp.sh
            tmp.sh: line 6: FOOBAR: command not found
            echo $?
            127





            share|improve this answer
























            • You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

              – Paul Hodges
              Nov 23 '18 at 18:42











            • If wait is last commend as shown then exit status will be whatever returned by wait

              – anubhava
              Nov 24 '18 at 2:23











            • Which is the logical compliment to what I said, lol ;)

              – Paul Hodges
              Nov 26 '18 at 13:58














            5












            5








            5







            You need to capture process id of background process and wait for it to set the correct exit status:



            #!/bin/bash
            set -eo pipefail

            rm -f mypipe
            mkfifo mypipe

            FOOBAR > mypipe &
            # store process id of above process into pid
            pid=$!

            cat mypipe

            # wait for background process to complete
            wait $pid


            Now when you run it:



            bash tmp.sh
            tmp.sh: line 6: FOOBAR: command not found
            echo $?
            127





            share|improve this answer













            You need to capture process id of background process and wait for it to set the correct exit status:



            #!/bin/bash
            set -eo pipefail

            rm -f mypipe
            mkfifo mypipe

            FOOBAR > mypipe &
            # store process id of above process into pid
            pid=$!

            cat mypipe

            # wait for background process to complete
            wait $pid


            Now when you run it:



            bash tmp.sh
            tmp.sh: line 6: FOOBAR: command not found
            echo $?
            127






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 23 '18 at 17:24









            anubhavaanubhava

            522k46318392




            522k46318392













            • You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

              – Paul Hodges
              Nov 23 '18 at 18:42











            • If wait is last commend as shown then exit status will be whatever returned by wait

              – anubhava
              Nov 24 '18 at 2:23











            • Which is the logical compliment to what I said, lol ;)

              – Paul Hodges
              Nov 26 '18 at 13:58



















            • You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

              – Paul Hodges
              Nov 23 '18 at 18:42











            • If wait is last commend as shown then exit status will be whatever returned by wait

              – anubhava
              Nov 24 '18 at 2:23











            • Which is the logical compliment to what I said, lol ;)

              – Paul Hodges
              Nov 26 '18 at 13:58

















            You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

            – Paul Hodges
            Nov 23 '18 at 18:42





            You need to explicitly capture/handle the return from wait if it isn't the last command in a script. You could set a trap.

            – Paul Hodges
            Nov 23 '18 at 18:42













            If wait is last commend as shown then exit status will be whatever returned by wait

            – anubhava
            Nov 24 '18 at 2:23





            If wait is last commend as shown then exit status will be whatever returned by wait

            – anubhava
            Nov 24 '18 at 2:23













            Which is the logical compliment to what I said, lol ;)

            – Paul Hodges
            Nov 26 '18 at 13:58





            Which is the logical compliment to what I said, lol ;)

            – Paul Hodges
            Nov 26 '18 at 13:58













            1














            If you need to be able to catch errors and apply specific behavior, a trap can be your friend. This code prints itself, so I just post a run here:



            $: tst
            + trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
            + rm -f mypipe
            + mkfifo mypipe
            + pid=6404
            + cat mypipe
            + cat ./tst
            #! /bin/env bash

            set -x

            trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
            #set -eo pipefail

            rm -f mypipe
            mkfifo mypipe

            cat $0 >mypipe &
            pid=$!
            cat mypipe
            wait $pid

            fubar >mypipe &
            pid=$!
            cat mypipe
            wait $pid

            echo done

            + wait 6404
            + pid=7884
            + cat mypipe
            + fubar
            ./tst: line 16: fubar: command not found
            + wait 7884
            ++ x=127
            ++ echo 127@./tst:19
            127@./tst:19


            Note the trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err line.
            It sets x to the last error code, which will be whatever triggered it. Then it prints the code, the filename, and the line number it is currently executing (before the trap) and exits the program with the error code. This actually triggers on the wait. It causes it to bail before continuing the echo at the bottom.



            It works with or without the set -eo pipefail.






            share|improve this answer






























              1














              If you need to be able to catch errors and apply specific behavior, a trap can be your friend. This code prints itself, so I just post a run here:



              $: tst
              + trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
              + rm -f mypipe
              + mkfifo mypipe
              + pid=6404
              + cat mypipe
              + cat ./tst
              #! /bin/env bash

              set -x

              trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
              #set -eo pipefail

              rm -f mypipe
              mkfifo mypipe

              cat $0 >mypipe &
              pid=$!
              cat mypipe
              wait $pid

              fubar >mypipe &
              pid=$!
              cat mypipe
              wait $pid

              echo done

              + wait 6404
              + pid=7884
              + cat mypipe
              + fubar
              ./tst: line 16: fubar: command not found
              + wait 7884
              ++ x=127
              ++ echo 127@./tst:19
              127@./tst:19


              Note the trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err line.
              It sets x to the last error code, which will be whatever triggered it. Then it prints the code, the filename, and the line number it is currently executing (before the trap) and exits the program with the error code. This actually triggers on the wait. It causes it to bail before continuing the echo at the bottom.



              It works with or without the set -eo pipefail.






              share|improve this answer




























                1












                1








                1







                If you need to be able to catch errors and apply specific behavior, a trap can be your friend. This code prints itself, so I just post a run here:



                $: tst
                + trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
                + rm -f mypipe
                + mkfifo mypipe
                + pid=6404
                + cat mypipe
                + cat ./tst
                #! /bin/env bash

                set -x

                trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
                #set -eo pipefail

                rm -f mypipe
                mkfifo mypipe

                cat $0 >mypipe &
                pid=$!
                cat mypipe
                wait $pid

                fubar >mypipe &
                pid=$!
                cat mypipe
                wait $pid

                echo done

                + wait 6404
                + pid=7884
                + cat mypipe
                + fubar
                ./tst: line 16: fubar: command not found
                + wait 7884
                ++ x=127
                ++ echo 127@./tst:19
                127@./tst:19


                Note the trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err line.
                It sets x to the last error code, which will be whatever triggered it. Then it prints the code, the filename, and the line number it is currently executing (before the trap) and exits the program with the error code. This actually triggers on the wait. It causes it to bail before continuing the echo at the bottom.



                It works with or without the set -eo pipefail.






                share|improve this answer















                If you need to be able to catch errors and apply specific behavior, a trap can be your friend. This code prints itself, so I just post a run here:



                $: tst
                + trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
                + rm -f mypipe
                + mkfifo mypipe
                + pid=6404
                + cat mypipe
                + cat ./tst
                #! /bin/env bash

                set -x

                trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
                #set -eo pipefail

                rm -f mypipe
                mkfifo mypipe

                cat $0 >mypipe &
                pid=$!
                cat mypipe
                wait $pid

                fubar >mypipe &
                pid=$!
                cat mypipe
                wait $pid

                echo done

                + wait 6404
                + pid=7884
                + cat mypipe
                + fubar
                ./tst: line 16: fubar: command not found
                + wait 7884
                ++ x=127
                ++ echo 127@./tst:19
                127@./tst:19


                Note the trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err line.
                It sets x to the last error code, which will be whatever triggered it. Then it prints the code, the filename, and the line number it is currently executing (before the trap) and exits the program with the error code. This actually triggers on the wait. It causes it to bail before continuing the echo at the bottom.



                It works with or without the set -eo pipefail.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 26 '18 at 14:03

























                answered Nov 23 '18 at 18:47









                Paul HodgesPaul Hodges

                3,1111322




                3,1111322






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53450561%2fcapture-non-zero-exit-code-from-named-pipe%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Berounka

                    Fiat S.p.A.

                    Type 'String' is not a subtype of type 'int' of 'index'