Root-Server Tutorial

ROOT-SERVER TUTORIAL

Creating Basic POSIX and Bash Scripts

How to learn to do basic POSIX and Bash scripting in Linux.

Author:

Patrick Zwick

Last updated:

04/11/2021

Introduction

In this tutorial, we will see how we can write basic POSIX compatible scripts. Scripts are very necessary in system administration and automation because once they are written, they make many tasks much easier.

Requirements

  • Server
  • Text editor (for example nano or vim)
  • Basic knowledge about the command line.

The Shebang

Each script starts with "the shebang". It specifies the path of the interpreter. For example:

##!/bin/bash

Or:

##!/bin/sh

These are the most common shebangs you will see. The difference between them is that the first script uses Bash as its interpreter, while the other is POSIX compliant and will run with any POSIX compliant shell like Bash. /bin/sh scripts have the advantage of running on most systems, while /bin/bash scripts only work with Bash, but can utilize some useful Bash extensions. This tutorial focuses on POSIX-compliant scripts, so in theory we can run our script with a shell like Dash instead of Bash. In the following examples, the shebang will be omitted, but it should always be present in your actual scripts.

Executing Commands

A script is basically nothing more than a list of commands:

echo "Hello World"
echo "This is a tutorial about scripting"

Comments

Comments are ignored by the interpreter and can be used to clarify issues. They can be created by writing a # before the message:

## This comment will be ignored by the interpreter

## The following command will echo something
echo Hello World

Variables

Variables hold values and are created like this:

var="A variable"
second_var="A second variable"

The contents of a variable can be accessed this way:

## Prints "A variable"
echo "$var"

The inverted commas (") can be omitted in some cases, but it is recommended to add them to avoid problems.

Setting the Value of a Variable to the Output of a Command

The value of a variable can be the output (STDOUT) of a command.

## The value of "var" is the output of the command "cat file".
var=$(cat file)

If Statements

If statements are an important feature of scripting. Let's take a look at them.

About Commands

Each command has an exit code. This is either 0 (everything went well) or something other than 0 (something went wrong). In If statements, our condition is a command. If its exit code is 0, the if statement is executed, if not, it is skipped.

Syntax

if <COMMAND>
then
    <COMMAND>
    <COMMAND>
    ...
fi

So let's take a look at this example:

if ping -c 1 -W 3 8.8.8.8
then
    echo "There is an active internet connection"
fi

If the ping to 8.8.8.8 is successful, the message will be displayed. We can also display another message if there is no internet connection. So let's add an else statement:

if ping -c 1 -W 3 8.8.8.8
then
    echo "There is an active internet connection"
else
    echo "There is no active internet connection"
fi

Comparing Numbers

There is no program available for comparing numbers. We will need to use our shell features:

first_var="1"
second_var="2"

if [ $first_var -gt $second_var ]
then
    echo "The first number is greater than the second"
else
    echo "The first number is not greater than the second"
fi

[ $first_var -gt $second_var ] is actually nothing more than a command provided by our shell. Its exit code is 0 if first_var is greater than second_var, or 1 if this isn't the case. So in general, -gt checks whether the first variable is greater than the second. Of course, there are other checks as well:

  • -gt: First number is greater than the second number.
  • -ge: First number is greater than or equal to the second number.
  • -lt: First number is smaller than the second number.
  • -le: First number is smaller than or equal to the second number.
  • -eq: Both numbers are the same.

Else If Statements

When comparing two numbers, there can be three cases:

  • The first number is greater than the second.
  • Both numbers are the same.
  • The second number is greater than the first.

In a script, we can check these conditions with an if, an elif and an else statement:

first_var="1"
second_var="2"

if [ $first_var -gt $second_var ]
then
    echo "The first number is greater than the second"
elif [ $first_var -eq $second_var ]
    echo "Both numbers are the same"
else
    echo "The second number is greater than the first"
fi

Negating If Statements

If statements can be negated using !, which means that the if statement will be executed if it actually wouldn't, and the other way around:

first_var="1"
second_var="2"

## This if statement will be executed if the first number is not greater than the second number.
if ! [ $first_var -gt $second_var ]
then
    echo "The second number is greater than the first or both numbers are the same"
fi

String Comparison

Strings can be compared like this:

first_var="hello"
second_var="hello"

if [ "$first_var" = "$second_var" ]
then
    echo "The first string is the same as the second"
fi

Note: Inverted commas (") are not needed when numbers are compared, but they must be used when strings are compared.

Comparing the Output of Commands

Let's compare the content of two files:

if [ "$(cat file1)" = "$(cat file2)" ]
then
    echo "file1 and file2 have the same contents"
fi

Other Checks

Checking if a variable exists:

## This If statement will be executed because var was not declared
if [ -z "$var" ]
then
    echo "Variable 'var' does not exist"
fi

Checking if a file exists:

if [ -f "file" ]
then
    echo "The file with the name 'file' does exist"
fi

The Sleep Command

We can use the sleep command to add a delay to our script (in seconds):

echo "Hello"

## Let's wait 3 seconds
sleep 3

echo "World"

Basic Math

Let's see how we can add, subtract, multiply, and divide two numbers:

first_var="10"
second_var="5"

## Addition
result_addition=$(($first_var + $second_var))
echo "$first_var + $second_var = $result_addition"

## Subtraction
result_subtraction=$(($first_var - $second_var))
echo "$first_var - $second_var = $result_subtraction"

## Multiplication
result_multiplication=$(($first_var * $second_var))
echo "$first_var * $second_var = $result_multiplication"

## Division
result_division=$(($first_var / $second_var))
echo "$first_var / $second_var = $result_division"

Please note that there are no floating point numbers in Bash. This means that the quotient of 3 and 4 ($((3 / 4))) is 0. Instead, a tool like bc is needed.

While Loops

While loops are executing commands when the exit code of a certain command is 0.

Syntax

while <COMMAND>
do
    <COMMAND>
    <COMMAND>
    ...
done

Infinite While statements are often needed to execute something periodically. Let's take a look at them:

while true
do
    sleep 2

    echo "Hello World"
done

In this case, true is again nothing more than a command provided by our shell, which always has the exit code 0. Statements often contain sleep statements so that they aren't executed too quickly.

Also, we can utilize While statements to execute a command several times (in the example below 5 times):

i=0

while [ $i -lt 5 ]
do
    echo "Current iteration: $i"

    i=$(($i + 1))
done

Running the Script

First the script must be made executable:

$ chmod +x my-script

Then we can run it:

$ /path/to/my-script

If the script is in our current working directory, it can be executed like this:

$ ./my-script

Conclusion

In this tutorial, you've learned how to write basic POSIX compliant scripts including commands, comments, variables, If statements, While statements, basic mathematical operations and delays.

License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributor's Certificate of Origin

By making a contribution to this project, I certify that:

  1. The contribution was created in whole or in part by me and I have the right to submit it under the license indicated in the file; or

  2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same license (unless I am permitted to submit under a different license), as indicated in the file; or

  3. The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.

  4. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the license(s) involved.

Published 04/11/2021 by Patrick Zwick

Submit your tutorial

Get 60€ netcup vouchers for every published tutorial.