Bash Cheatsheet - Command Line Utilities & Scripting

Comprehensive Bash cheatsheet covering essential commands, one-liners, if statements, loops, functions, and output redirection for efficient shell scripting.

Bash Cheatsheet

Bash Scripting Essentials

This Bash cheatsheet provides a quick reference for common command-line utilities and scripting techniques. Master these to enhance your productivity and efficiency in the Linux/Unix environment.

Explore essential Bash concepts:

Core Bash Commands

The `tr` Command for Text Transformation

The `tr` command is a powerful utility for translating or deleting characters. It's invaluable for text manipulation in scripts.

Example: Removing whitespace from a string:

$ echo 'foo - bar' | tr -d '[:space:]'
foo-bar

Example: Converting text to uppercase:

$ echo 'HeLLo' | tr '[:lower:]' '[:upper:]'
HELLO

Practical Bash One-Liners

Automated IP Blocking with `iptables`

This section demonstrates how to parse log files to identify and block malicious IP addresses using `iptables`, a fundamental firewall utility.

First, extract suspicious IP addresses from a mail log:

$ cat /var/log/maillog | grep 'lost connection after AUTH from unknown' | tail -n 5
May 10 11:19:49 srv4 postfix/smtpd[1486]: lost connection after AUTH from unknown[185.36.81.145]
May 10 11:21:41 srv4 postfix/smtpd[1762]: lost connection after AUTH from unknown[185.36.81.164]
May 10 11:21:56 srv4 postfix/smtpd[1762]: lost connection after AUTH from unknown[175.139.231.129]
May 10 11:23:51 srv4 postfix/smtpd[1838]: lost connection after AUTH from unknown[185.211.245.170]
May 10 11:24:02 srv4 postfix/smtpd[1838]: lost connection after AUTH from unknown[185.211.245.170]

Isolate just the IP addresses:

cat /var/log/maillog | grep 'lost connection after AUTH from unknown' | cut -d'[' -f3 | cut -d ']' -f1 | tail -n5
185.36.81.164
175.139.231.129
185.211.245.170
185.211.245.170
185.36.81.173

Obtain a unique list of these IPs:

$ cat /var/log/maillog | grep 'lost connection after AUTH from unknown' | cut -d'[' -f3 | cut -d ']' -f1 | sort | uniq
103.194.70.16
112.196.77.202
113.172.210.19
113.173.182.119
139.59.224.234

Apply the `iptables` rule to block each identified IP on port 25 (SMTP):

$ for ip in $(cat /var/log/maillog | grep 'lost connection after AUTH from unknown' | cut -d'[' -f3 | cut -d ']' -f1 | sort | uniq); do iptables -I INPUT -s ${ip} -p tcp --dport 25 -j DROP; done

Conditional Logic in Bash

Checking for Command-Line Arguments

Ensure your scripts receive the necessary input by checking if arguments have been provided.

if [[ $# -eq 0 ]] ; then
    echo 'Error: No arguments provided. Please supply arguments.'
    exit 1
fi
echo 'Arguments received.'

Validating Specific Argument Values

Verify that the first argument meets specific criteria.

if [ "$1" == "one" ] || [ "$1" == "two" ]
then
  echo "Argument 1 is either 'one' or 'two'."
  exit 0
else
  echo "Error: Argument 1 must be 'one' or 'two'."
  exit 1
fi

Alternatively, check if a variable is set:

NAME=${1}
if [ -z "${NAME}" ]
  then
    echo "Error: NAME variable is undefined."
    exit 1
  else
    echo "Hello, ${NAME}!"
fi

Verifying Environment Variable Existence

Ensure critical environment variables are set before proceeding.

if [ -z "${OWNER}" ] || [ -z "${NAME}" ]
then
  echo "Error: Required environment variables (OWNER, NAME) are not set."
  exit 1
else
  echo "Required environment variables are present."
fi

Bash Loops for Automation

Executing a Process for a Fixed Duration

Control the execution time of background processes using `while` loops and `sleep`.

set -ex
count=0
echo "Starting process..."
ping localhost & # Start ping in the background
while [ $count -le 5 ]
  do
    sleep 1
    count=$((count + 1))
    echo "Running for: $count seconds"
  done
ps aux | grep ping # Verify the process is running
echo "Process duration complete."
kill $! # Terminate the background process
sleep 2
echo "Process stopped."

Looping Until a State Change with a Timeout

Implement robust waiting mechanisms that handle state changes and prevent indefinite execution.

UPDATE_COMPLETE=false
UPDATE_STATUS="running" # Initial status
MAX_RETRIES=10
current_retry=0

while [ "$UPDATE_COMPLETE" = false ] && [ "$current_retry" -lt "$MAX_RETRIES" ]
    do
        echo "Checking update status... Retry: $((current_retry + 1))/$MAX_RETRIES"
        sleep 1
        current_retry=$((current_retry + 1))

        # Simulate status checks
        if [ "$current_retry" -eq 7 ]; then
            UPDATE_STATUS="successful"
        fi

        if [ "$UPDATE_STATUS" == "running" ]; then
            echo "Update is still running."
        elif [ "$UPDATE_STATUS" == "successful" ]; then
            UPDATE_COMPLETE=true
            echo "Update completed successfully."
        else
            echo "Error: Unexpected update status '$UPDATE_STATUS'."
            exit 1
        fi
    done

if [ "$UPDATE_COMPLETE" = false ]; then
    echo "Error: Update timed out after $MAX_RETRIES seconds."
    exit 1
fi
echo "Final status confirmed."

`for` Loops for Iteration

Batch Loading Docker Images

Efficiently load multiple Docker images from `.tar` files using a `for` loop.

for image_tar in *.tar; do
  if [ -f "$image_tar" ]; then
    echo "Loading Docker image: $image_tar"
    docker load -i "$image_tar"
  fi
done

Bash Functions for Reusability

Encapsulate logic into functions to promote code reuse and modularity.

Function to greet a user:

greet_user(){
    local user_name=${1}
    echo "Hello, ${user_name}!"
}
greet_user "Alice"

Function accepting multiple arguments:

display_message(){
    echo "Message: $@"
}
display_message "This is the first part." "And this is the second."

Advanced Output Redirection

Managing Standard Output (stdout) and Standard Error (stderr)

Gain fine-grained control over where your command outputs go.

Discarding standard error:

grep -irl faker . 2>/dev/null

Redirecting stdout to one file and stderr to another:

grep -irl faker . > output.log 2> error.log

Redirecting stderr to stdout, then redirecting combined output to a file:

grep -irl faker . > combined_output.log 2>&1

Redirecting both stdout and stderr to a single file:

grep -irl faker . &> all_output.log

Text Manipulation Techniques

Extracting Substrings from Strings

Bash provides efficient ways to manipulate string variables.

Remove the first 3 characters from a string:

$ STRING="abcdefghij"
$ echo "${STRING:3}"
defghij

Extracting the Last Characters of a String

Isolate the trailing characters of a string.

Using parameter expansion to get the last 3 characters:

$ STRING="abcdefghij"
$ echo "${STRING: -3}"
hij

Note: The `tail -c` command can also be used for this purpose on the output of `echo`.

For more advanced Bash scripting, consult the official Bash manual and resources like the GNU Bash Reference Manual and ExplainShell.