Table of Contents
- Getting Started
- Comments
- Variables
- Loops
- Conditionals
- Case
- Functions
- User Input
- Arithmetic
- Arrays
- Debugging Shell scripts
- Tips and Tools
Getting Started
Create a text file called script with a .sh file extension (not required) and add the contents below to it.
#!/bin/bash
echo "Hello, World!"
You have to make the shell script you just created executable by running this:
sudo chmod +x script.sh
Now you can run the script to see the message printed to the screen with
source script.sh
Hello, world!
Comments
Like all other programming languages, you can add comments in your scripts to describe exactly what your script does. Bash scripts support single line and multi-line comments.
Single line comments
#!/bin/bash
# This is a single line comment
echo "Hello, world!"
Multi-line comments
#!/bin/bash
: '
This is a multi-line comment
spanning not just one line
but many lines
'
echo "Hello, world!"
Variables
There are two types of variables in Bash,
- User-defined variables: are variables defined by a user in the shell script and are usually in all lowercase.
#!/bin/bash
message="Shell scripting tutorial"
echo $message
- Shell defined variables: are variables defined by the Bash shell and are usually in all uppercase.
#!/bin/bash
echo $BASH_VERSION
There are a number of builtin Bash variables:
$$ - PID of the current shell
$! - PID of last background command
$? - Exit status of the last command
$0 - Name of the current command
$1 - Name of the current command's first parameter
$9 - Name of current command's ninth parameter
$@ - All of the current command's parameters (preserving whitespace and quoting)
$* - All of the current command's parameters (not preserving whitespace and quoting)
Formatting Variables
# The string 'Not defined' is printed if the variable "message" has not been defined.
echo ${message:-"Not defined"}
# The string "Not defined but now defined and assigned", if the variable did not exist prior.
echo ${message:="Not defined but now defined and assigned"}
# The string "Error: the variable does not exist" is printed if you try to print a variable does not exist.
echo ${message:?"Error: the variable does not exist"}
var1='shell scripting'
var2='BASH SCRIPTING'
echo ${var1^^} # Print a variable in all uppercase.
echo ${var1^} # Convert the first letter to uppercase.
echo ${var2,,} # Print a variable in all lowercase.
echo ${var2,} # Convert the first letter to lowercase.
Loops
C-style for loops
#!/bin/bash
for ((i=0; i<10; i++))
do
echo $i
done
Python style for loops
#!/bin/bash
for number in "1 2 3 4 5"
do
echo $number
done
While loops
#!/bin/bash
count=0
while [[ $count -lt 10 ]]
do
echo $count
(( count++ ))
done
Until loops
#!/bin/bash
count=10
until [[ $count -eq 0 ]]
do
echo $count
(( count-- ))
done
Select loops
You can use select loops to create menu type interfaces to shell scripts.
#!/bin/bash
options="Yes No Maybe"
ps3="Select your option" # Customize your menu selection.
select option in $options
do
if [[ $option == "Yes" ]]
then
echo "You chose Yes"
elif [[ $option == "No" ]]
then
echo "You chose No"
exit
elif [[ $option == "Maybe" ]]
then
echo "You chose Maybe"
else
echo "Invalid option chosen"
exit
fi
done
Conditionals
Bash supports the usual if, elif and else conditional operators of other programming languages.
Supported Bash comparison operators are:
- Integer comparison operators
- String comparison operators
- Compound comparison operators
- File comparison operators
Integer comparison operators
-eq is equal to
-ne is not equal to
-gt is greater than
-ge is greater than or equal to
-lt is less than
-le is less than or equal to
< is less than – place within double parentheses
<= is less than or equal to
> is greater than
>= is greater than or equal to
String comparison operators
= is equal to
== is equal to
= is not equal to
< is less than ASCII alphabetical order
> is greater than ASCII alphabetical order
-z string is null (i.e. zero length)
-n string is not null (i.e. !zero length)
Compound comparison operators
-a logical and
-o logical or
#!/bin/bash
a=1
b=2
if [[ $a -gt $b ]]
then
echo $a is greater than $b
elif [[ $a -lt $b ]]
then
echo $a is less than $b
elif [[ $a -eq $b ]]
then
echo $a is equal to $b
else
echo "unknown condition"
fi
[[ -e "$file" ]] # True if file exists
[[ -d "$file" ]] # True if file exists and is a directory
[[ -f "$file" ]] # True if file exists and is a regular file
[[ -z "$str" ]] # True if string is of length zero
[[ -n "$str" ]] # True is string is not of length zero
-r file has read permission
-w file has write permission
-x file has execute permission
file1 -nt file2 file file1 is newer than file2
file1 -ot file2 file file1 is older than file2
file1 -ef file2 files file1 and file2 are hard links to the same file
[[ ... ]] && [[ ... ]] # And
[[ ... ]] || [[ ... ]] # Or
Case
A Case statement can simplify and replace a collection of if elif else statements and it can also be used with the Select statement.
#!/bin/bash
read -p "Make your choice: " option
case $option in
"Yes")
echo "You chose 'Yes'";;
"Maybe")
echo "You chose 'Maye'";;
"No")
echo "You chose 'No'";;
*) # default option
echo "Unknown option";;
esac
# Create a Menu system with Select and Case
options="Yes No Maybe"
select option in $options
do
case $option in
"Yes")
echo "You chose 'Yes'";;
"Maybe")
echo "You chose 'Maye'";;
"No")
echo "You chose 'No'"
exit;;
*) # default option
echo "Unknown option";;
esac
done
Functions
Functions in Bash work like in regular programming languages, the only difference is the invocation i.e. you execute a function by typing the name only with no brackets. Also, Bash functions do not have a return value.
#!/bin/bash
# Define a simple function
function greeter() {
echo "Hello, world!"
}
# Define a function that accepts arguments
function greeter1() {
echo $1
}
Call the function by running
greeter
to display:
Hello, World!"
And call the function by passing in arguments
greeter Hello, world
to display:
Hello, World!"
User input
You can accept user input with Bash with the read keyword
#!/bin/bash
read var # The user inputted value is saved in a variable called *var*
read -p "Enter your name" name # A prompt "Enter your name" is displayed to the user and the supplied value is saved in the variable "name".
read -s -p "Enter your password" password # "This hides the user inputted value. Useful for password inputs.
read -p "Enter all your names" -a names # If you want to accept more than one value from users. It creates an Array object called *names*
Arithmetic
#!/bin/bash
a=1
b=2
$((a + b)) # Addition
$((a - b)) # Subtraction
$((a * b)) # Multiplication
$((a / b)) # Division
$((a % b)) # Modulus
If you want to do advanced arithmetic like dealing with floats, finding square roots of numbers, etc, you should use the inbuilt bc command.
#!/bin/bash
echo "scale=2; sqrt((49)) | bc -l # scale determines the number of decimal places.
echo "scale=3; 3.142 * 4.2" | bc -l
Arrays
In Bash, there are two kinds of variables
- Scalar variables (contains a single value)
- Arrays variables (contains multiple values) Bash arrays are Zero-based arrays i.e. start from position zero.
#!/bin/bash
names=(Jack John Jill Scot)
${names[@]} # This prints all the variables
${#names[@]} # Counts the number of items in the *names* array.
${!names[@]} # Returns the indexes of the items in the array.
unset names[<index>] # Removes the item in the array at the specified index.
${names[0]} # Returns the first item of the array.
${names[-1]} # Returns the last item of the array.
Tips, Tricks, and Tools
- Use shellcheck.net to find bugs in your shell scripts.
- You can debug your shell scripts running it like
bash -x script.sh
. This runs the script in debug mode. - You can set breakpoints in your shell scripts
#!/bin/bash
set -x
message="This is a shell scripting tutorial"
echo $message
set +x
So we have come to the end of this 5-minute introduction to Bash shell scripting. I hope it will start you on your journey to more mastery.
Top comments (2)
Great post! Well done!
I wrote a similar thing a couple of weeks ago actually:
Getting started with Bash scrippting
Awesome work!!!