3 ms·
Bash is the only language I know where if cond; then x; else y; fi does not do the same thing as if ! cond; then y; else x; fi despite the the absence o
by dataflow 4y ago
Bash is the only language I know where
if cond; then x; else y; fi
does not do the same thing as
if ! cond; then y; else x; fi
despite the the absence of any operator overloading.
- nikau 4y agoCurious on this one, do you have an example showing it not working as expected?
- dataflow 4y ago$ if false; then :; else (if [ $? -eq 0 ]; then echo msg; fi); fi $ if ! false; then (if [ $? -eq 0 ]; then echo msg; fi); else :; fi msg
- nikau 4y agoThat's correct behavior though. You should do if ARG=false Then use $ARG not $? in the if statement.
- dataflow 4y agoIt's the best kind of correct, yes.
- nikau 4y agoIt's a pretty bizarre use case, why would you need the second if statement, you already are in logic based on the return code I can't think of an example of the if statement being confusing that isn't relying on $?
- dataflow 4y agoerror=0 if ! some_command; then error=$?; bar; fi echo "blah" return $error
- nikau 4y agoYep that's a valid scenario, if you need more granularity than just fail or success then you will have to use a different method, e.g. Status=0 Somecommand || status=$? Then do logic based on status
- somat 4y agoYep as a programing language shell is weird, I am sure you know this better than me, but I got nerd sniped by your snippet, and want say what I think is happening. false the command returns 1, ! the command turns a 0 return code into a 1 and anything other than a zero into a 0, if is vaguely backwards from most languages in that it deals in return codes a rc of 0 is true and anything else is false in the first case false has a rc of 1 this will execute the else list then the test command 1 is equal to 0(rc = 1 false list) so "msg" does not print in the second case false(rc 1), !(rc 0), if(true list) now you check if rc is 0, it is and "msg" is printed.
- dataflow 4y agoYeah. Basically instead of treating ! specially, Bash treats it like any other command that sets $? afterwards. And since it always succeeds, you always end up with $?=0 after it. I don't know what kind of shell scripts the designers of this write, but the number of times I've wanted or found it helpful for ! to modify $? is has been exactly zero. I am almost certain that >99% of people who write shell scripts do not find this intuitive.
- trashtester 4y ago> Yeah. Basically instead of treating ! specially, Bash treats it like any other command that sets $? afterwards. And since it always succeeds, you always end up with $?=0 after it. I don't think that is true, consider: # if false ; then echo "true $?" ; else echo "false $?" ; fi false 1 # if ! false ; then echo "true $?" ; else echo "false $?" ; fi true 0 # if ! ! false ; then echo "true $?" ; else echo "false $?" ; fi false 1 Basically, $? evaluates to the full condition inside the "if" sentence. One of the first things I learned when starting to use $? was to assign it to a variable asap if I needed to use it more than once.
- dataflow 4y agoWhoops, that's what I get for writing these when I'm sleepy. Yes of course ! doesn't always set the result to success, that wouldn't make any sense. I misspoke in that part. I meant to say Bash treats it like any other command that modifies $?, instead of treating it specially and preventing it from modifying that variable. Thanks.
- Ferret7446 4y agoYour original claim is disingenuous. Of course cond = false if cond; then x; else (if cond; then echo msg); fi does not do the same thing as cond = true if cond; then (if cond; then echo msg); else x; fi Bash is not somehow strange in this regard.
- dataflow 4y agoThere's neither anything disingenuous about my claim. Bash's behavior is quite unique and unexpected to most people in the examples I showed. And I don't appreciate the attack.
- masklinn 4y agoIsn’t sql an other one?