Why does set -e; true && false && true not exit?

前端 未结 3 1461
无人及你
无人及你 2020-12-07 01:30

According to this accepted answer using the set -e builtin should suffice for a bash script to exit on the first error. Yet, the following script:



        
3条回答
  •  长情又很酷
    2020-12-07 01:37

    I came across set -e for Bash scripts but had problems understanding what happens regarding the evaluation of the command following the last && or || in a && or || list. I know of the following quote from http://man7.org/linux/man-pages/man1/bash.1.html about set -e:

    The shell does not exit if the command that fails is (...) part of any command executed in a && or || list except the command following the final && or || (...)

    To test this, I wrote a small Bash script:

    #!/bin/bash
    
    bash -c "set -e ; true           ; echo -n A"
    bash -c "set -e ; false          ; echo -n B"
    bash -c "set -e ; true  && true  ; echo -n C"
    bash -c "set -e ; true  && false ; echo -n D"
    bash -c "set -e ; false && true  ; echo -n E"
    bash -c "set -e ; false && false ; echo -n F"
    bash -c "set -e ; true  || true  ; echo -n G"
    bash -c "set -e ; true  || false ; echo -n H"
    bash -c "set -e ; false || true  ; echo -n I"
    bash -c "set -e ; false || false ; echo -n J"
    
    echo ""
    

    It prints:

    ACEFGHI
    

    About A:

    true does not have a non-zero status. Therefore, the shell doesn't exit.

    About B:

    false does have a non-zero status and is not part of a && or || list. Therefore, the shell exits.

    About C:

    This is a && or || list. We will have to look at the command following the last && or ||. The command is true which does not have a non-zero status. So it doesn't matter if the command is evaluated or not - the shell doesn't exit either way.

    About D:

    This is a && or || list. We will have to look at the command following the last && or ||. This time, the command is false which does have a non-zero status. So we have to check if that false is being evaluated - which is indeed the case since && is following the true. Therefore, the shell exits.

    About E:

    Same reasoning as with C: true is the command following the last && or ||. Therefore, the shell doesn't exit.

    About F:

    Similar to D: This is a && or || list. We will have to look at the command following the last && or ||. Again the command is false which does have a non-zero status. But this time it doesn't matter, because the first command is false as well. Since it's a && list, the second false won't be evaluated. Therefore, the shell doesn't exit.

    About G:

    Same reasoning as with C or E: true is the command following the last && or ||. Therefore, the shell doesn't exit.

    About H:

    This is a && or || list. We will have to look at the command following the last && or ||. This command is false which does have a non-zero status, but it won't be evaluated since || is preceded by true. Therefore, the shell doesn't exit.

    About I:

    Same reasoning as with C, E or G: true is the command following the last && or ||. Therefore, the shell doesn't exit.

    About J:

    This is a && or || list. We will have to look at the command following the last && or ||. This command is false which does have a non-zero status. Since || is preceded by false the second false will be evaluated. Therefore, the shell does exit.


    You should be able to apply these test cases to your case: true && false && true. Since the command following the last && or || is true which doesn't have a non-zero status, it doesn't matter what precedes && or ||, the shell won't exit either way.

提交回复
热议问题