Commands, Variables, Loops, and Automation
Bash scripting allows you to automate repetitive tasks in Linux by combining commands into scripts that execute in sequence. Instead of repeatedly typing the same commands into a terminal, you can save them in a file and execute them whenever needed.
This is useful for everyday Linux administration, file management, system checks, and scheduled tasks.
This guide covers the fundamentals of Bash scripting, from creating your first script to working with loops, processing files, debugging, and scheduling automated tasks.
1. What Is a Bash Script?
A Bash script is a text file containing commands that the Bash shell can interpret and execute.
For example, instead of typing several commands individually, you can save them in a script and execute them together.
Create a file called hello.sh:
#!/bin/bash
echo "Hello, World!"
echo "Today is $(date)"
Let's break this down.
-
#!/bin/bash— The shebang identifies the interpreter to use when the script is executed directly. -
echo— Prints text to standard output. -
$(date)— Runs thedatecommand and substitutes its output into the surrounding command.
To make the script executable, run:
chmod u+x hello.sh
Then execute it:
./hello.sh
The terminal will display the messages and the current date.
Why use scripts?
Scripts reduce repetitive work, make tasks easier to reproduce, and provide a foundation for automating system administration.
2. Variables and User Input
Variables allow scripts to store and reuse values.
Consider this example:
#!/bin/bash
name="Wale"
echo "My name is $name"
Here, name is a variable containing the value Wale.
The $name expression retrieves that value.
Notice that there are no spaces around the = when assigning a value in Bash:
name="Wale"
This is different from:
name = "Wale"
The second example is not a valid variable assignment in Bash.
Accepting user input
The read command allows a script to receive input from the user.
#!/bin/bash
echo "What is your name?"
read -r name
echo "Hello, $name!"
When executed, the script waits for the user to enter a name and press Enter.
The entered value is stored in the name variable and displayed in the final message.
The -r option prevents read from treating backslashes as escape characters.
Passing arguments to a script
You can also supply values when executing a script.
Consider greeting.sh:
#!/bin/bash
echo "My name is $1"
Execute it with:
./greeting.sh Wale
Output:
My name is Wale
Here, $1 represents the first positional argument passed to the script.
For example:
-
$1— First argument. -
$2— Second argument. -
$3— Third argument.
This allows scripts to accept different values without requiring interactive input.
3. Working with Files and Command Output
Linux commands can read from files and redirect their output into files.
Understanding these operations is essential for writing useful scripts.
Redirecting output
The > operator redirects command output into a file.
ls > output.txt
This writes the directory listing to output.txt.
Important: If the file already exists, > overwrites its contents.
To append output instead, use >>:
echo "Another entry" >> output.txt
This adds the new text to the end of the file without replacing the existing contents.
Reading file contents
The cat command displays a file's contents:
cat output.txt
By contrast:
ls output.txt
lists the file itself rather than displaying its contents.
Reading input from a file
The < operator redirects a file's contents into a command's standard input.
For example:
while IFS= read -r line
do
echo "$line"
done < output.txt
This reads output.txt one line at a time and prints each line.
The expression:
done < output.txt
redirects the loop's standard input from the file.
This pattern is useful when processing text files line by line.
4. Understanding Loops
Loops allow a script to repeat commands without requiring you to write the same instructions multiple times.
Bash supports several types of loops, including while and for.
The while loop
A while loop continues executing as long as its condition is true.
#!/bin/bash
i=1
while [[ $i -le 5 ]]
do
echo "$i"
((i += 1))
done
Output:
1
2
3
4
5
How it works:
-
i=1initializes the variable. -
[[ $i -le 5 ]]checks whetheriis less than or equal to 5. -
domarks the beginning of the commands to execute. -
echo "$i"prints the current value. -
((i += 1))increments the variable by one. -
donemarks the end of the loop.
When i becomes 6, the condition is false and the loop stops.
Watch out: If the variable never changes in a way that makes the condition false, the loop may run indefinitely.
The for loop
A for loop is useful when iterating over a known sequence of values.
#!/bin/bash
for i in {1..5}
do
echo "$i"
done
Output:
1
2
3
4
5
Here, {1..5} expands into the sequence of numbers from 1 to 5.
The loop assigns each value to i and executes the commands inside the loop.
Unlike the previous example, you don't need to increment the variable manually.
5. Using case for Multiple Conditions
The case statement allows a script to compare a value against several patterns and execute the commands associated with the first matching pattern.
For example:
#!/bin/bash
fruit="apple"
case "$fruit" in
apple)
echo "This is an apple."
;;
orange)
echo "This is an orange."
;;
*)
echo "This fruit is not recognized."
;;
esac
Output:
This is an apple.
Here's what the syntax means:
-
case "$fruit" in— Begins the comparison. -
apple)— Matches the valueapple. -
;;— Ends that case and exits thecasestatement. -
*)— Acts as the default pattern when no earlier pattern matches. -
esac— Marks the end of the statement.
The case statement is useful when a script needs to respond differently to multiple possible inputs.
For example, it can process user choices, command-line options, or service names.
6. Debugging Bash Scripts
A script may fail because of incorrect syntax, unexpected input, or incorrect assumptions about how a command behaves.
Bash provides tools to help identify these problems.
Using set -x
Add this line near the beginning of your script:
#!/bin/bash
set -x
Bash will print commands and their expanded arguments to standard error as it executes them.
For example:
#!/bin/bash
set -x
name="Wale"
echo "Hello, $name"
The trace helps you see how Bash interprets and executes the commands.
You can also enable tracing for a particular section:
set -x
# Commands to investigate
set +x
The first command enables tracing, while the second disables it.
This is useful when you want to investigate a specific part of a script rather than trace every command.
Security note: Be careful when debugging scripts that handle passwords, access tokens, or other secrets. Tracing can expose sensitive values in terminal output or logs.
7. Scheduling Scripts with Cron
Some tasks need to run automatically at particular times.
For example, you might want a script to run every morning, periodically check a service, or perform a routine maintenance task.
On Linux systems that use cron, scheduled jobs can be managed with crontab.
Viewing scheduled jobs
Run:
crontab -l
This displays the current user's scheduled cron jobs.
To edit them, run:
crontab -e
Understanding cron syntax
A standard cron expression contains five fields:
* * * * *
│ │ │ │ │
│ │ │ │ └── Day of the week
│ │ │ └──── Month
│ │ └────── Day of the month
│ └──────── Hour
└────────── Minute
Each field controls when the scheduled command runs.
Example 1: Run a script every day at midnight
0 0 * * * /path/to/script.sh
The five fields specify minute 0, hour 0, and every day, month, and weekday.
The script runs at midnight each day, according to the cron daemon's time settings.
Example 2: Run a script every five minutes
*/5 * * * * /path/to/script.sh
The */5 expression means every five minutes.
Practical consideration: When scheduling scripts, use appropriate file permissions and valid paths. Cron jobs may also need explicit environment variables or logging because they don't necessarily run with the same environment as your interactive terminal.
Conclusion
Bash scripting provides a practical way to automate tasks in Linux.
The fundamentals covered here—variables, user input, positional arguments, file redirection, loops, conditional selection, debugging, and scheduling—form a foundation for more advanced automation.
As scripts become more complex, these concepts can be combined to perform repetitive administrative tasks, process files, and support infrastructure operations.
The key is to understand what each command does, how the pieces fit together, and how to verify that a script behaves as expected.
Top comments (0)