Dev 101: Shell in a nutshell
In the Dev 101 series I cover some basic concepts of computer programming for a broad audience. I guess it’s the explanation I was looking for myself, when I first started out as a programmer…
In a previous installment of the Dev 101 series, I explained the concept of the shell — a command language interpreter that executes commands read from standard input, a command line string, or a specified file.
This means that shell can be used either interactively via the terminal:
tdeneire@XPS-13-9370:~$ sh
$ echo "hello"
hello
$ exit
tdeneire@XPS-13-9370:~$
or as a CLI:
sh -c "echo $(date)"
or to execute Shell scripts, saved as .sh
files like this:
#!/bin/shecho "Hello world"
You can then execute them with sh myfile.sh
Especially the last option is a fantastic tool for writing scripts for automation, installation, configuration, and so on.
Because knowing your way around Shell scripts is a vital tool for any developer working with UNIX systems, I will try to summarize Shell syntax below.
I’ve taken care to limit this summary to “pure” UNIX shell syntax, i.e. the Bourne shell or sh
. Most Unix-like systems contain the file /bin/sh
that is either the Bourne shell, or a symbolic link (or hard link) to a compatible shell (e.g. dash
). The reason for sticking to sh
is that different shell versions (bash, dash, ksh, zsh, …) all come with different features, although they are mostly sh-compatible. By sticking to sh
syntax you allow your scripts to be executed by a variety of shells, which makes them dependable and robust.
Hello world
echo "Hello World!"
Comments
# This is a comment
Variable assignment
NAME_1="Tom" # set
readonly NAME_1 # read-only
unset NAME_1 # unset
Quoting (strong vs weak)
Quoting variables prevents word splitting and glob expansion, and prevents the script from breaking when input contains spaces, line feeds, glob characters and such.
$ echo '$HOME'
$HOME
$ echo "$HOME"
/home/tdeneire
Arrays
# POSIX shell does not support array variables!
# dash, bash, ksh and others do, however
User input
echo "Enter user name: "
read -r FIRST_NAME
echo "Current user name is $FIRST_NAME"
Operators (arithmetic)
VAL=$((2 + 2))# + (Addition)
# - (Subtraction)
# * (Multiplication)
# / (Division)
# % (Modulus)
# = (Assignment)
# == (Equality)
# != (Not Equality)
Operators (relational)
[ "$VAL" -eq 4 ]
# -eq (equal)
# -ne (not equal)
# -gt (greater than)
# -lt (less than)
# -ge (greater or equal)
# -le (less or equal)
Operators (boolean)
# && (AND)
# || (OR)
# ! (NOT)
Operators (string)
NAME="Tom"
[ "$NAME" = "Tom" ]# = (equal)
# != (not equal)
# -z (zero length)
# -n (non-zero length)
# str (not empty)
Conditional statements (if…elif…else)
NAME="Tom"if [ "$NAME" = "Tom" ];
then
echo "me"
elif [ "$NAME" = "Peter" ];
then
echo "my cousin"
else
echo "someone else"
fi
Conditional statements (case)
NAME="Tom"case $NAME in
"Tom")
echo "me"
;;
"Peter")
echo "my cousin"
;;
*)
echo "someone else"
;;
esac
Loops
For
for NUMBER in 0 1 2 3 4 5 6 7 8 9
do
echo $NUMBER
done
While
I=0
while [ $I -lt 10 ]
do
echo $I
I=$(($I + 1))
done
Until
I=0
until [ ! $I -lt 10 ]
do
echo $I
I=$(($I + 1))
done
Break
for VAR1 in 1 2 3
do
for VAR2 in 0 5
do
if [ $VAR1 -eq 2 ] && [ $VAR2 -eq 0 ]
then
break 2
else
echo "$VAR1 $VAR2"
fi
done
done
Continue
NUMS="1 2 3 4 5 6 7"for NUM in $NUMS
do
Q=$(($NUM % 2))
if [ $Q -eq 0 ]
then
echo "$NUM is an even number"
continue
fi
echo "Found odd number: $NUM"
done
Command substitution
echo "Date is $(date)"
Functions
Hello () {
echo "Hello, $1"
return 0 # Can only return 0-255. Other data should be written
to stdout
}Hello "Tom"
RETURN=$?echo "This command exited with code $RETURN"
Sources
Hi! 👋 I’m Tom. I’m a software engineer and a writer. My content is free, but if you want, you can support me at https://www.buymeacoffee.com/tomdeneire