💾 Archived View for mateuszreszka.xyz › posts › how-bash-if-really-works › index.gmi captured on 2024-09-29 at 00:00:20. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-06-20)
-=-=-=-=-=-=-
You probably never think of it but behind every bash script stands tons of if-else statements which are responsible for whole script logic, as error gates or even correctness of operations. What if I told you that bash shell does not really interpret if statements itself? A test library serves that purpose and this is what this article is really about.
Testing library usually located at `/usr/bin/test` is a GNU util which is responsible for comparing expressions and values against each other. The result of the comparison is an `exit code` of `0` or `1`, depending whether the operation was successful. Here is an example that demonstrates that behavior:
$ test 3 -gt 2 ; echo $? 0 $ test 1 -gt 2 ; echo $? 1
Let's describe what is happening in that simple test in details.
1. `test` library gets called with three arguments:
- first expression
- type of comparison (there `-gt` which means `greater than`)
- second expression
1. Semicolon says we want to wait for the last operation to end.
1. `echo $?` checks the status code of the previous operation. `0` means that it was successful and no errors occurred.
Bash serves multiple ways to write if statements, one of them is calling them using `if` keyword and square braces, like so:
if [ -n "$VARIABLE" ]; then echo 'variable exists' fi
What actually happens behind the curtain is something like this:
[ -n "$VARIABLE" ] && echo 'variable exists'
Which means pretty much the same as:
test -n "$VARIABLE" && echo 'variable exists'
Quote from the `info test` documentation
test has an alternate form that uses opening and closing square brackets instead a leading ‘test’. For example, instead of ‘test -d /’, you can write ‘[ -d / ]’. The square brackets must be separate arguments; for example, ‘[-d /]’ does not have the desired effect. Since ‘test expr’ and ‘[ expr ]’ have the same meaning, only the former form is discussed below.
Reference: https://www.gnu.org/software/coreutils/manual/html_node/test-invocation.html#test-invocation
Many developers has troubles to figure out what flags are actually supported. __Use provided manuals__. I can't think of how often it saved my ass to just look for the flag I need instead of craft something myself. GNU `man` is awesome for that type of a thing along with `info`.
$ man test
That will pop-up full fledged manual for all possible use cases for test library, i.e. join two expressions `test 3 -gt 2 -a 3 -gt 1` thanks to `-a` flag.
I really encourage you to check what else `test` can do in your bash scripts and try to use it in various ways as much as possible, it's single the most useful library you'll ever use in that field. The more standard and well tested your tools are, the safer your scripts will be!