shell - Subshell created using (...) behaves differently from bash -c '...' -


i use set -e inside (...) on command line doesn't exit subshell when false command executed.

code 1:

( set -e; echo "$bashpid: start"; false; echo "foobar"; date; ) &&    echo "$bashpid: ok" || echo "$bashpid: nope" 9136: start foobar wed, apr 29, 2015  7:14:24 pm 7292: ok 

however if use bash -c subshell creation behaves expect.

code 2:

bash -c 'set -e; echo "$bashpid: start"; false; echo "foobar"; date;' &&   echo "$bashpid: ok" || echo "$bashpid: nope" 7880: start 7292: nope 

interestingly if remove && , || part after subshell (...) behaves fine.

code 3:

( set -e; echo "$bashpid: start"; false; echo "foobar"; date; ) 5940: start 

so conclusions getting are:

  1. (...) behaves differently bash -c
  2. (...) && false behaves differently (...) , changes behavior of subshell well.

am making obvious mistake in interpreting strange (at least me) behavior?

the behavior of set -e && intentional.

it explicitly doesn't trigger when command part of && sequence.

from posix spec:

-e

when option on, when command fails (for of reasons listed in consequences of shell errors or returning exit status greater zero), shell shall exit following exceptions: failure of individual command in multi-command pipeline shall not cause shell exit. failure of pipeline shall considered.

the -e setting shall ignored when executing compound list following while, until, if, or elif reserved word, pipeline beginning ! reserved word, or command of and-or list other last.

if exit status of compound command other subshell command result of failure while -e being ignored, -e shall not apply command.

this requirement applies shell environment , each subshell environment separately. example, in:

set -e; (false; echo one) | cat; echo 2 

the false command causes subshell exit without executing echo one; however, echo 2 executed because exit status of pipeline (false; echo one) | cat zero.

i assume difference here whether shell knows fact.

(...) presumably because current shell executes , bash -c presumably doesn't because that's external process (or something).

that last bit speculation , mind sub-shell behavior here entirely unhelpful , makes set -e unreliable (which why many people suggest avoiding it).

though seems might provide sort of "escape hatch" reliability problem if explicitly run shell doesn't have issue composition of scripts.


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -