The Type System of Bash
Every programming language has a type system. The good ones make it explicit. And then there is Bash.
14 February 2020Ask a question
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.
Thus 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
, Hello
and World
,
where echo
is the function, returning its arguments Hello
and 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" )
The inner echo
expands to Hello
World
which in turn as arguments to the
outer echo
results in "Hello World".
Using $(( ... ))
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.
EDIT: There are also arrays. That's topic for another post.
Ask us Anything. We'll get back to you shortly