4 ms·
> Yeah I didn't explain that very well. Not at all well, I'm afraid, but I think I understand: f(){ false && true; } ; set -e ; f ; echo hi # this works c
by a1369209993 6y ago
> Yeah I didn't explain that very well.
Not at all well, I'm afraid, but I think I understand:
f(){ false && true; } ; set -e ; f ; echo hi
# this works correctly (f returns false and errexit triggers)
set -e; false && true ; echo hi
# despite `false && true` failing, this doesn't trigger errexit
I was confused by the implication that the function version was what was wrong (rather than "false && true is broken, and you'd expect the function to work the same way"). Probably partly because I was confusing it with `command || true`, which is a idiomatic way to suppress errexit-like mechanisms by making the exit status always 0.
- chubot 6y agoWell, which one is broken depends on your viewpoint, and the exact use case. Another way to look at it is the difference between exercise 4 and 5 here: https://mywiki.wooledge.org/BashFAQ/105 https://mywiki.wooledge.org/BashFAQ/105 So taking that concrete example test -d nosuchdir && echo "warning: no directory"; instead of false && true You didn't want the function to fail. You just wanted to print a warning if the directory doesn't exist. But the whole function fails, while it doesn't for the if statement. The whole thing is inherently confusing ... The language confuses success/failure and true/false. Both of those are stuffed into an exit code. test -d is really for true/false, but then functions also have success/failure (did the last command succeed). So there's no way for shell to really know what you want. I think Oil might end up with something like "if catch foo" for success/fail, and "if boolean grep" for true/false.
- a1369209993 6y ago> You just wanted to print a warning if the directory doesn't exist. That code prints a warning if the directory does exist, actually ("-d FILE FILE exists and is a directory"). Did you mean something like: test -e outfile && echo "trying to overwrite preexisting outfile" > You didn't want the function to fail. Uh, I kind of do, actually? If I wanted to discard the exit status I'd write: test -e outfile && echo "trying to overwrite preexisting outfile" || true; This is awkward, and suggests a proper if-then operator (perl-6-style `??` collides with globbing, but maybe `&?`?), but it's better then having something like: mkfoo -o foo && cp -T foo otherfoo do-something foo bar mostly-silently mix old and new data together because mkfoo failed and the error code was swallowed. > So there's no way for shell to really know what you want. Yep, and if we have to pick one problem, things failing completely in a obvious and also easily-fixable way is usually a much less awful problem to have than silently corrupting data and state, especially when you've opted-in to a mechanism (like errexit) specifically designed to do the former.