Bash Basics PDF
Bash Basics PDF
Contents
First script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Introduction to Bash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Comments in Bash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Shebang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
echo command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Loading a file into a variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Variables display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Command substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Save to file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Standard streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Redirection operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Input redirection example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Output redirection example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Error redirection example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
The arguments and the If statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Array of arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Argument variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Conditional tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Numeric operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
String operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
File system operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
If statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
If/else statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
If/elif/else statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
While statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
For statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Local variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Arithmetic expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Expr instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Let instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Double parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1
First script
Introduction to Bash
Bash is a system shell available on most GNU/Linux distributions. It is a kind of interface between the
user and the system.
When we type commands in the console, they are not sent directly to the system - they are first inter-
preted by the shell. Thanks to this, we can use conditional statements, create loops, function aliases or
subroutines.
A Bash script is a sequence of commands written in a text file. When ran, they are executed line by line
by the Bash interpreter.
Comments in Bash
We use comments to describe how our script and/or parts of it work. This allows third parties (or us in
the future) to understand the program faster, without having to run it.
To create a comment in Bash, use the symbol # (hash). The text from the hash to the end of the line will
be ignored by the interpreter - it will not look for code there.
Shebang
#!/bin/bash
echo command
echo - command for displaying text in the console. As an argument, it accepts a string surrounded by “
symbols. By default, the command adds a newline character at the end of the string.
Usage example:
#!/bin/bash
echo "The first message."
echo "The second message."
Output:
The first message.
The second message.
2
Loading a file into a variable
Variables
Variables in Bash don’t have types. They can contain numerical values, character values or strings. You
don’t need to declare variables, just assign a value to them.
Variable creation example:
#!/bin/bash
var1=10
var2="a string of characters"
Variables display
Variable values can be displayed using the familiar echo command. It is enough that in the text after echo
we give the name of our variable after the symbol $.
#!/bin/bash
var1=10
var2="number"
echo "$var1"
echo "Our $var2 is $var1"
Output:
10
Our number is 10
Command substitution
Using the $() construct, we can pass the standard output of another program to our variable in Bash. In
parentheses, specify the command whose output you want to capture.
#!/bin/bash
path=$(pwd)
echo "Current path: $path"
Output:
Current path: /home/jan_kowalski/bash
3
Save to file
Standard streams
There are three standard streams in GNU/Linux:
0. stdin - standard input stream containing data transferred to the program,
1. stdout - standard output stream containing program output data (including e.g. echo),
2. stderr - standard error stream containing error messages.
When running the program from the console, data typed on the keyboard will be transferred to the stdin
stream. The stdout and stderr streams will be displayed in the terminal where we launched the program.
Redirection operators
Standard streams can be redirected manually using the < and > operators.
The < operator is used to redirect the input data to the program, and the > operator is used to redirect
the output data from the program.
It will count the number of characters entered from the keyboard until the program is terminated. How-
ever, we can pass it using the < operator.
wc -m < file.txt
Now the wc program will not wait for input from the keyboard, but will display the number of characters
in the file.txt file on the screen.
file.txt
This text will be in the file
error.txt
mv: missing file operand
Try 'mv --help' for more information.
4
The arguments and the If statement
Array of arguments
In Bash, we can easily access the positional arguments provided when we run a script.
All positional arguments are automatically entered into a special table **$@**. We most often use it when
we want to iterate through all the arguments, e.g. using a for loop. The following script prints out all the
arguments line by line.
#!/bin/bash
for arg in "$@"
do
echo "$arg"
done
By invoking it as follows:
./main.sh one 2 three
Argument variables
We can access individual arguments using special variables that are named after a set of integers.
• The variable $0 contains the name of the script file.
• The variable $1 contains the value of the first given argument.
• The variable $2 contains the value of the second given argument.
• …
• The variable $n contains the value of the nth given argument.
Below is an example of a program that reads an argument directly from its variable:
#!/bin/bash
echo "The second argument: $2"
5
Conditional tests
To perform logical tests in Bash, we use the [ command, which is an alias of the test command. It allows
you to check a single condition. This command returns 0 if the condition is true and 1 if the condition is
false (contrary to most programming languages).
To test more than one condition, we can combine [ statements using the logical conjunction operator &&
and the logical disjunction operator ||. Note the spaces between square brackets and expressions.
Below is an example of two combined tests:
[ expression1 operator expression2 ] && [ expression3 operator expression4 ]
There are many operators that we can use in conditional tests. They fall into three categories - numeric,
string and file system.
Numeric operators
[ INT1 -eq INT2 ] - true if both numbers are equal.
[ INT1 -ne INT2 ] - true if the numbers are different.
[ INT1 -ge INT2 ] - true if the first number is greater than or equal to the second number.
[ INT1 -gt INT2 ] - true if the first number is greater than the second number.
[ INT1 -le INT2 ] - true if the first number is less than or equal to the second number.
[ INT1 -lt INT2 ] - true if the first number is less than the second number.
String operators
[ STR1 = STR2 ] - true if both strings are identical.
[ STR1 != STR2 ] - true if the strings are different.
[ STR1 < STR2 ] - true if the first string is lexicographically before the second.
[ STR1 > STR2 ] - true if the first string is lexicographically after the second.
[ -n STR ] - true if the string is longer than zero characters.
[ -z STR ] - true if the length of the string is zero.
6
[ -k FILE ] - true if the file exists and its sticky bit is set.
[ -L FILE ] - true if the file exists and is a symbolic link (same as -h).
[ -N FILE ] - true if the file exists and has been modified since the last read.
[ -O FILE ] - true if the file exists and belongs to the effective user.
[ -p FILE ] - true if the file exists and is a named link.
[ -r FILE ] - true if the file exists and can be read.
[ -s FILE ] - true if the file exists and has size greater than zero.
[ -S FILE ] - true if the file exists and is a socket.
[ -t FD ] - true if the file descriptor is opened in the terminal.
[ -u FILE ] - true if the file exists and has the SUID flag set.
[ -w FILE ] - true if the file exists and can be written.
[ -x FILE ] - true if the file exists and can be executed.
[ FILE1 -nt FILE2 ] - true if the first file is newer than the second.
[ FILE1 -ot FILE2 ] - true if the first file is older than the second.
[ FILE1 -ef FILE2 ] - true if both files are hardlinked to the same file.
If statement
if <condition>
then
statements
fi
The if statement checks whether the given condition is true - if so, the commands between the then
keyword and the fi keyword will be executed. Otherwise, Bash will skip to the next commands (after the
fi) statement.
Example of use:
#!/bin/bash
if [ -e ~/.bashrc ]
then
echo "You have a file .bashrc"
fi
7
If/else statement
if <condition>
then
commands1
else
commands2
fi
The if/else statement checks whether the given condition is true - if so, the statements between the then
keyword and the else keyword (commands1) will be executed. Otherwise, the commands between the
else keyword and the fi (commands2) keyword will be executed.
Example of use:
#!/bin/bash
if [ -e ~/.bashrc ]
then
echo "You have a file .bashrc"
else
echo "You don't have a file .bashrc"
fi
If/elif/else statement
if <condition1>
then
commands1
elif <condition2>
then
commands2
else
commands3
fi
The if/elif/else statement checks if the first given condition (condition1) is true - if so, the statements
between the first occurrence of the then keyword and the first occurrence of the elif keyword will be
executed (commands1). Otherwise, the condition given in the next command elif (condition2) will be
checked. If the second condition is true, the commands between the second then and the else keyword
(commands2) will be executed. If the second condition is also false, the commands between else and fi
(commands3) will be executed. We can add infinitely many conditions using the elif statement.
8
Example of use:
#!/bin/bash
if [ $1 -eq 10 ]
then
echo "Your number is 10!"
elif [ $1 -eq 4 ]
then
echo "Your number is 4!"
elif [ $1 -eq 23 ]
then
echo "Your number is 23!"
else
echo "I have no more ideas..."
fi
Loops
While statement
while <condition>
do
statements
done
The while loop is used to conditionally repeat a statement. Commands between the keywords do and
done will be executed as long as the condition given at the while statement is true. The condition is
checked before each iteration.
Example of use:
#!/bin/bash
i=0
while [ $i -lt 5 ]
do
(( i += 1))
echo "Iteration $i"
done
Output:
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
9
For statement
The for loop is used to iterate through a list of words. In most programming languages, this behavior is
reserved for for each loops. A word can be a string or an expandable expression. With each iteration, the
temporary variable variable will be assigned the next read value from the list. The commands between
the keywords do and done will be executed as many times as many there are elements in the list.
Example of use:
#!/bin/bash
for $i in 1 2 3 4 5
do
echo "Iteration $i"
done
Output:
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
Subroutines
Functions
Functions in Bash, also called subroutines, are minor scripts included in our program. We can pass argu-
ments to them the same way as to the entire script. Functions can be created in two ways and it is up to
us which one we prefer to use.
function_name() {
statements
}
function function_name {
statements
}
welcome John
welcome Alice
10
Output:
Hello John!
Hello Alice!
Local variables
By default, all variables created in bash are global - we can use them anywhere in the script. However, it
is good practice to isolate the variables created in the function with the local keyword. This means that
the variable preceded by this word will only be available in the block of our function.
Example of use:
#!/bin/bash
f() {
local var=42
echo "$var"
}
f
echo "$var"
Output:
42
The value 42 was displayed only once because the var variable does not exist outside the f() function
block.
Arithmetic expressions
When we want to calculate anything in Bash, we’re going to use arithmetic expressions. By default, we can
perform operations on integers - to use floating point numbers, you need to use external tools (e.g. awk,
bc).
Expr instruction
The expr function displays the result of a given expression between two numbers on the screen.
Available operators are:
•+
– addition
•-
– subtraction
• *
– multiplication
• /
– division
• %
– modulo (division remainder)
Example of use:
#!/bin/bash
expr 7 * 5
11
Output:
35
Let instruction
We use the let function to assign the result of an arithmetic expression to a variable. It does not display
the result of the operation on the screen. We can also use other variables in expressions. The available
operations are:
• -<variable>
– opposite number
• **
– exponentiation
• *
– multiplication
• /
– division
• %
– modulo (division remainder)
•+
– addition
•-
– subtraction
• *=, /=, %=, +=, -=
– assignment linked to action
Example of use:
#!/bin/bash
var1=5
var2=4
let "result = var1 ** var2"
echo "$result"
Output:
625
Double parentheses
We can use double parentheses as an alias to the let function as follows:
((variable = expression))
However, we can use the comparison operators < and > without using \.
Example of using double parentheses as a conditional test:
a=10
if ((a > 5))
then
echo "a is greater than 5"
fi
Output:
12
a is greater than 5
13