I'm trying to comprehend what are all the possible constructs you can pass to if in bash.
In the GNU reference:
The syntax of the if statement is:
if test-commands; then consequent-commands; [elif more-test-commands; then more-consequents;] [else alternate-consequents;] fi The test-commands list is executed, and if its return status is zero, the consequent-commands list is executed...
So I understand that test-commands may be anything that returns a status. So first I thought that this must be one of the followings:
- the test built-in (i.e. [ ] )
- The [[ ]] syntax
- some command (may be any executable)
And as I knew the test command, it has a ! operator (among others) that can inverse the return of the conditional statement you put in it, as such:
if [ ! -z "non-empty" ]; then echo "ok"; fi Until then I was happy thinking I know bash. But then I found that I can do:
if ! [ -z "non-empty" ]; echo "Ok!"; fi That breaked my heart - I thought that the ! thing belongs to the test command (also to the [[]] syntax) - but what is it outside of it? And why does if takes it?
What construct exactly is ! ? And are there other things acceptable?
[ ! ... ]exclamation point (part of the syntax of thetestcommand) is a different exclamation point from the! [ ... ]exclamation point (negation of a pipeline status), and neither are directly tied toif.!only has anything to do withtest/[when you use it inside atestexpression. The other times it's part of regular shell syntax and usable anywhere (not just inif). See the POSIX sh standard at pubs.opengroup.org/onlinepubs/9699919799/utilities/… specifying the not-testversion, and pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html specifying thetestversion.ifmust be a command (and this can be any command). If the command terminates with exit code 0, thethenbranch is taken; otherwise it's theelsepart. No fancy syntax here.what are all the possible constructs you can pass to if in bashyou can put anything insideif, you can write the whole script insideif, there are no limits. For example a loop and another expression inside anif:if i=0; while ((i++ < 5)); do ((j=i*2)); done; ((j == 10)); then echo "j=$j"; fi;. The!is like similar in construct likeiforwhile, it just inverts the exit status of the command (actually whole pipeline). Butcommand !-!is just a string, just like inecho ifwould printif. If the string!is passed to[command, then[reacts in specific way.what is it outside of it?is it's the first word in the list, it's a negation, if it is not the first word, it's just string!(but, also except history expansion).why does if takes it?any list of commands takes it! echo 1, even! if true; then echo 2; fiWhat construct exactly is ! ?It's part of pipeline as noted above andAnd are there other things acceptable?Yes,!ifwhilecaseuntilare basically parsed the same way, see pubs.opengroup.org/onlinepubs/009604499/utilities/…