The Type System of Bash
Every programming language has a type system. The good ones make it explicit. And then there is Bash.
Of all programming / scripting languages, the type system of Bash is probably the most obscure and even more error-prone than that of Perl. It is so inconspicuous that may people are misled to believe that Bash is "untyped". But like any language, Bash has its types.
The type system is very simple. There are only three of them: string, integers and, most importantly, lists. However, complexity arises due to two factors:
Latent typing. The type of a value is determined at runtime based on its context.
1 can be either the integer 1 or the string "1".
Evaluation. Bash is very much like Lisp. And Bash expressions are, mostly, S-expressions. If you understand Lisp, then you understand Bash (and AST, stack machine and programming in general).
A S-expression is -- in simple layman's term -- a list where the first element is the function / command / programme, and the rest are the arguments.
echo Hello World # echo is the function and it prints the two arguments, # separated by one blank space, to the terminal. echo Hello World # gives you the same result, the number of blank spaces # inbetween does not matter.
In the above example, we have a list of three elements,
echo is the function, returning its arguments
World separated by
one blank space.
If you want to print out "Hello World" with the exact number of whitespaces, you have to put white spaces under single or double quotes to tell Bash that it is an argument, and not separator.
echo "Hello World" # echo gets one argurment. echo Hello " " World # echo gets three arguements -> same result. echo Hello " " " " World # echo gets four arguments -> same result.
So in Bash everything is a list where the elements are separated by whitespaces (tab or space character). The element of a list can, depending on the context, be either a string, an integer or an expression that expands to elements.
A="Hello World" # Variable A is assigned the string "Hello World". echo $A # The dollar operator $ expands the variable resulting # effectively in: echo Hello World B="echo Hello World" $B # The variable expands to the expression: echo Hello World # which in turn is evaluated in the CLI.
You can also evaluate the result of a function with
$( ... ) or
echo $( echo "Hello World" )
echo expands to
World which in turn as arguments to the
echo results in "Hello World".
$(( ... )) you can evaluate arithmetic expressions.
echo $(( 1 + "2" )) # Quotes don't matter echo $(( 2 ** 63 - 1 )) # maximum echo $(( 2 ** 63 )) # minimum echo Hello $(( 8 / 4 )) # Within $((...)) integers are integers, # and outside of it, they are strings.
However, there is no support for floating-point numbers.
echo $(( 1 ** 3.14 )) # -> syntax error: invalid arithmetic operator
That's it. In summary, Bash is typed and the types are integers, strings and lists.