$ if false; then :; else (if [ $? -eq 0 ]; then echo msg; fi); fi
$ if ! false; then (if [ $? -eq 0 ]; then echo msg; fi); else :; fi
msgYou should do
if ARG=false
Then use $ARG not $? in the if statement.
I can't think of an example of the if statement being confusing that isn't relying on $?
error=0
if ! some_command; then error=$?; bar; fi
echo "blah"
return $errorStatus=0
Somecommand || status=$?
Then do logic based on status
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.
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.
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.
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.