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!

Similar Posts