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:
- Useful One-Liners
- Blocking Malicious IPs
- Conditional Logic (If Statements)
- Argument Handling
- Variable Existence Checks
- Environment Variable Checks
- Looping Constructs (While Loops)
- Time-Limited Process Execution
- Advanced Output Redirection
- Standard Output and Standard Error
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.