5 ms·
Wait until you realize set -e; (false && true); echo hi does nothing, but set -e; false && true ; echo hi prints hi.
by mehrdadn 6y ago
Wait until you realize
set -e; (false && true); echo hi
does nothing, but
set -e; false && true ; echo hi
prints hi.
- Sebb767 6y agoIt's a bit surprising at first, but I'd like to think most people deeper into bash are aware of Subshells.
- alanbernstein 6y agoI know $() invokes a subshell, but does () ? My guess was that the () affects the order of operations between ; and &&, so the first line is three commands, while the second line is two.
- aidenn0 6y agoIt's a subshell. Order of operations is unchanged, and if you just want a block of commands you can use { }
- asicsp 6y agoSee https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Command-Grouping https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.... "Placing a list of commands between parentheses causes a subshell environment to be created" "Placing a list of commands between curly braces causes the list to be executed in the current shell context"
- gravitas 6y agoIt's horribly more complex than just that, the person you're replying to is "more correct" because of the rules of `set -e` which is critical in this thread; a singular command followed by && is treated differently than a compound command. Pull up `man bash` and search `/set.*abef` to read the rather long and involved paragraph for the `-e` option, running in a subshell is only part of it.
- asicsp 6y ago>I know $() invokes a subshell, but does () ? >My guess was that the () affects the order of operations between ; and &&, so the first line is three commands, while the second line is two. Emphasis mine. My understanding was that the question is simply about whether () invokes a subshell or not (irrespective of set -e)
- mehrdadn 6y agoMerely knowing about when subshells occur doesn't explain this. You need to know that && and || suppress -e.
- chubot 6y agoYeah this is a variation on problem 2 I mentioned here, except with subshells rather than functions. https://news.ycombinator.com/item?id=24740842 https://news.ycombinator.com/item?id=24740842 The problem actually has more to do with the definition of $? than the set -e behavior itself. And the fact that POSIX specifies that the error a the LHS of && is ignored (a fundamental confusion between true/false and success/error) The exit code of the function is not what you expect, or the exit code of the subshell is not what you expect. I made a note of it on the bug ... still thinking about what the solution to that one is. (The other solutions are inherit_errexit, more_errexit, and a "catch" builtin.)
- cryptonector 6y agoThat one is OK. What's NOT OK is that conditionals disable set -e in functions that appear in the conditionals, so: function foo { false; true; } foo || echo foo failed prints nothing.
- mehrdadn 6y agoOuch, that's horrible. Thanks!
- chubot 6y agoYes, that's #1 the "if myfunc" problem I mentioned here: https://news.ycombinator.com/item?id=24740842 https://news.ycombinator.com/item?id=24740842 shopt -s strict_errexit in Oil disallows that (a runtime assertion 100% of the time). Feedback is welcome! https://github.com/oilshell/oil/issues/709 https://github.com/oilshell/oil/issues/709