As a full-stack developer and professional Linux coder, bash scripting is an essential skill for automating tasks and improving productivity. Mastering bash opens up a world of possibilities for building tools, deployments, and more.
In this comprehensive guide, I will walk through 30 practical bash script examples to demonstrate the most common and useful techniques you need to know. From basic syntax, variables, conditions, loops, functions, all the way to advanced use cases like reading files, sending emails, etc.
By the end, you will have a solid foundation to start writing your own advanced bash scripts. Let‘s get started!
1. Hello World Bash Script
Let‘s start with the good old "Hello World" example. Here is how you would print "Hello World" in bash:
#!/bin/bash
echo "Hello World"
To execute this, simply save it as a file like hello.sh and run:
$ bash hello.sh
Hello World
The #!/bin/bash line at the top called the shebang tells the system this script should be interpreted by the bash shell. Then we use the echo command to print our message.
2. Using Variables
Here is an example of using variables in bash:
#!/bin/bash
name="John"
echo "Hello $name!"
Save and execute this script, and it will print "Hello John!".
The name variable holds our string "John", which is interpolated into the echo command via the $name placeholder.
3. Taking User Input
We can take user input in a bash script like this:
#!/bin/bash
read -p "Enter your name: " name
echo "Hello $name!"
The -p flag to read prints a prompt message, then reads the user input into our $name variable. Run this script and it will prompt you for your name, then greet you!
4. If-Else Conditional
Here is an if-else example in bash:
#!/bin/bash
num=3
if [[ $num -lt 10 ]]; then
echo "$num is less than 10"
else
echo "$num is greater than 10"
fi
This evaluates whether $num is less than 10 using -lt for "less than", then prints a message based on the result. The if and fi delimit the conditional block.
5. For Loop
Here is an example of a for loop in bash that prints numbers:
#!/bin/bash
for i in {1..10}; do
echo $i
done
This constructs a sequence from 1 to 10 using brace expansion {1..10}, then prints each number. The for starts the loop, do starts the body, and done ends it.
6. While Loop
A while loop executes as long as its condition is true. Here is an example:
#!/bin/bash
count=1
while [ $count -le 5 ]; do
echo $count
count=$((count+1))
done
This initializes a count variable to 1, then keeps looping while count is less than or equal to 5. $((count+1)) increments count each iteration. Finally, count prints and the loop continues!
7. Case Statement
A case statement often serves as an alternative to multiple nested if-else blocks. It compares a value against different patterns:
#!/bin/bash
read -p "Enter y/n: " ans
case "$ans" in
[Yy]* ) echo "You said yes";;
[Nn]* ) echo "You said no";;
* ) echo "Invalid input";;
esac
Here we take user input, then match it against uppercase or lowercase y/n. The * works like an else to catch invalid input. Each pattern match ends with ;;.
8. Arrays
Bash supports one-dimensional arrays. Here is an example declaring and using an array:
#!/bin/bash
fruits=(‘Apple‘ ‘Banana‘ ‘Orange‘)
echo "First fruit: ${fruits[0]}"
echo "Number of fruits: ${#fruits[@]}"
This initializes an array fruits with three values. We print the first value at index 0, then get the length with a special #@ syntax.
Arrays provide an efficient way to store collections of data.
9. Functions
Here is an example of defining and calling a function in bash:
#!/bin/bash
greeting() {
echo "Hello, $1!"
}
greeting "John"
We define the greeting function which accepts one parameter $1. Inside the function, this will refer to the first argument passed. Then we call greeting and pass "John", which prints "Hello, John!".
Functions help organize and reuse code.
10. Taking Command Line Arguments
We can access command line arguments passed to a bash script like this:
#!/bin/bash
echo "Total arguments: $#"
echo "1st argument: $1"
echo "2nd argument: $2"
$# prints the number of args, $1 prints the first arg, $2 the second, and so on. Save this script as args.sh and run bash args.sh fox cat. It will print:
Total arguments: 2
1st argument: fox
2nd argument: cat
This allows passing dynamic data to scripts.
11. Reading Files
We can read a file line-by-line in bash with a while loop like this:
#!/bin/bash
while IFS= read -r line; do
echo "$line"
done < "./data.txt"
The IFS= prevents leading/trailing whitespace from being trimmed. The \-r flag prevents backslash escapes from being interpreted. The < "./data.txt" redirects the data.txt contents into the while loop for processing.
This iterates each line, with the echo printing them out.
12. Writing to a File
We can write output to a file like so:
#!/bin/bash
echo "This will write to output file" > ./out.txt
The > character redirects the output of the echo command to the out.txt file. Any existing contents will be overwritten.
We could also append output with >> instead:
echo "This will append to output file" >> ./out.txt
13. Parsing CSV Data
Deliminated data is very common. Here is an example script to parse some comma-separated (CSV) data:
#!/bin/bash
cat data.csv | while IFS=‘,‘ read firstname lastname age; do
echo "$firstname is $age years old"
done
We use while to process each line, setting the Internal Field Separator (IFS) to ‘,‘ so $firstname, $lastname, etc. divide the line appropriately.
This shows how bash can turn data into useful information.
14. Finding IP Address
To programmatically find your external IP address:
#!/bin/bash
IP=$(curl -s ifconfig.me)
echo "My public IP is: $IP"
We use curl to download ifconfig.me then trim output with -s. This saves the result into $IP which we print.
15. Waiting for a Process
We can also wait for a process to finish with the wait command:
#!/bin/bash
ping google.com &
PID=$!
# Do other stuff...
echo "Waiting for ping process $PID"
wait $PID
echo "Ping finished"
The & runs ping in the background. $! saves that background process‘s PID.
Later, we use wait $PID to pause the script until ping completes.
16. Parsing Options with getopts
We can parse command line options by importing getopts. Here is an example script:
#!/bin/bash
while getopts ":ab:" opt; do
case $opt in
a)
echo "-a flag set" >&2
;;
b)
echo "-b $OPTARG" >&2
;;
esac
done
This defines two options, -a and -b, where -b accepts an argument afterward. Inside the case, we print which is set.
This makes scripts very customizable from various params!
17. Checking Disk Space
To programmatically check disk usage in bash:
#!/bin/bash
SPACE=$( df -h | grep /$ | awk ‘{print $5}‘ | cut -d‘%‘ -f1 )
if [[ $SPACE -gt 90 ]]; then
echo "Running out of disk space ($SPACE%)"
fi
We use a pipeline – df to show disk usage, grep to filter to our root drive, awk to extract the percentage, then cut to parse it. If over 90% we issue a warning.
18. List only Directories
Here is how to list only directories from the current location in bash:
#!/bin/bash
for item in */; do
echo "$item"
done
The */ glob finds all subdirectories, then we echo print each one.
19. Copy File Preserving Permissions
To copy files while preserving permissions:
#!/bin/bash
cp -p source.txt destination.txt
The -p flag retains the original source.txt permissions on the newly copied destination.txt.
20. Generate Random Password
We can generate a random password with:
#!/bin/bash
PW_LENGTH=10
CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
password=$(for i in $(seq $PW_LENGTH); do sort --random-sort <(printf %s ${CHARS// /\\n} | shuf) | head -1; done | paste -sd ‘‘ -)
echo "Random password: $password"
Here shuf and sort generate random characters, which get compiled into the $password variable. We set length with PW_LENGTH.
21. Finding Files Modified in Last N Days
To find files modified in the last N days:
#!/bin/bash
find . -type f -mtime -5 -ls
Here find searches recursively -mtime -5 days back (adjust N) and -ls prints detailed info per file.
22. Calculate Folder Size
We can get a total folder size in bash with:
#!/bin/bash
du -sh folder1
The du command calculates disk usage for folder1 with -h printing human readable format and -s totaling sizes.
23. Playing Audio Alert
We can play an audible alert in a bash script with:
#!/bin/bash
play -nq -t alsa synth 0.1 sin 880 vol 0.2
The play command handles audio output, taking parameters for note -n, tempo -q, device -t, waveform type synth, duration 0.1, note sin 880 and volume.
This allows scripts to talk back audibly!
24. Sending Email Alerts
To send emails from bash scripts:
#!/bin/bash
RECIPIENT="admin@mydomain.com"
SUBJECT="Alert"
BODY="CPU usage over 90%"
echo "$BODY" | mail -s "$SUBJECT" "$RECIPIENT"
The mail command takes the message body from stdin and sends it as an email. Useful for admin alerts!
25. Executing SQL Queries
If working with databases, we can execute SQL from bash scripts like:
#!/bin/bash
RES=$(echo "SELECT * FROM table;" | sqlite3 test.db)
echo "Query result: $RES"
This passes a query to sqlite3, saves the result into $RES, and prints it out. The sqlite3 tool makes scripting databases easy.
26. Comparing Version Numbers
To compare semantic version numbers in bash:
#!/bin/bash
ver1="2.3.1"
ver2="1.12.0"
if [[ "$(printf ‘%s\n‘ "$ver1" "$ver2" | sort -V | head -n1)" != "$ver1" ]]; then
echo "ver1 ($ver1) is old"
fi
We printf each version in a sort-friendly format. -V does a version sort so 1.12 sorts after 2.3. If ver1 is alphabetically first, it is oldest.
27. Parsing XML Data
To extract values from an XML document with bash:
#!/bin/bash
xml=‘<data><id>123</id><url>foo.com</url></data>‘
id=$(echo $xml | sed -n ‘s/.*<id>\(.*\)<\/id>.*/\1/p‘)
echo "Extracted ID: $id"
Here sed does a regex match to capture the contents of the <id> tag. This is then assigned to $id and printed.
28. Running As Another User
We can run commands or scripts as another user with sudo:
#!/bin/bash
script="myscript.sh"
sudo -u otheruser bash "$script"
The -u flag specifies otheruser. We call bash explicitly to run our $script as that user.
29. Self-Elevating Script
For scripts needing sudo access without prompting for passwords, use:
#!/bin/bash
[ "$UID" -eq 0 ] || exec sudo bash "$0" "$@"
# Script logic here runs as root
Here we check if $UID is 0 (root), and exec sudo if not, passing all arguments. This re-runs the script elevated without altering remaining logic.
30. Updating Script from Inside
To automatically update a script from within itself:
#!/bin/bash
version=2.0
if [[ $(wget -qO- https://domain.com/script.sh) != "$0" ]]; then
echo "Script updated! Restarting..."
exec bash "$0" "$@"
fi
# Regular script logic follows...
This wget‘s the remote script, checks if different from local via $0, then exec re-runs itself to activate updates.
And there you have it – 30 incredibly useful bash script examples to apply for everything from task automation to advanced use cases. Bash scripts demonstrate the immense power at your fingertips for improving productivity and simplifying redundant work.
The examples here aim to spark ideas and provide a solid foundation to start writing your own advanced scripts. Linux offers a vast playground if you know which tools to string together for custom solutions. Challenge yourself to put bash through its paces – the sky‘s the limit on what you can build!


