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.
> 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:
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.
Another way to look at it is the difference between exercise 4 and 5 here:
https://mywiki.wooledge.org/BashFAQ/105
So taking that concrete example
instead of 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.