02.1 – Conditionally execute code (use of: if, test, [], etc.)
Conditionally executing code is a fundamental skill for shell scripting in Linux. It allows scripts to perform specific actions based on certain conditions. Below are detailed notes on using conditional statements in , with examples.
1. Conditional Execution with if Statement
Syntax:
if [ condition ]; then
# Commands to execute if condition is true
fi- The condition is evaluated inside square brackets (
[]). - If the condition is true (exit status
0), the commands within theifblock are executed.
Example:
#!/bin/bash
if [ -e /etc/passwd ]; then
echo "/etc/passwd exists."
fiExplanation:
-echecks if the file exists.- If
/etc/passwdexists, the message is printed.
2. Adding an else Block
Syntax:
if [ condition ]; then
# Commands if condition is true
else
# Commands if condition is false
fi
Example:
#!/bin/bash
if [ -d /tmp ]; then
echo "/tmp is a directory."
else
echo "/tmp is not a directory."
fiExplanation:
-dchecks if the path is a directory.- If
/tmpis a directory, the first message is printed; otherwise, the second message is printed.
3. Using elif for Multiple Conditions
Syntax:
if [ condition1 ]; then
# Commands if condition1 is true
elif [ condition2 ]; then
# Commands if condition2 is true
else
# Commands if none of the conditions are true
fiExample:
#!/bin/bash
num=10
if [ $num -gt 20 ]; then
echo "Number is greater than 20."
elif [ $num -eq 10 ]; then
echo "Number is equal to 10."
else
echo "Number is less than 20 but not 10."
fiExplanation:
-gt: Greater than.-eq: Equal to.- Conditions are checked sequentially until one evaluates to true.
4. The test Command
The test command evaluates conditions without using [].
Syntax:
test conditionExample:
#!/bin/bash
if test -f /etc/hosts; then
echo "/etc/hosts is a regular file."
fiExplanation:
-fchecks if the file is a regular file.
5. Combining Conditions with Logical Operators
Logical AND (-a) and OR (-o)
if [ condition1 -a condition2 ]; then
# Commands if both conditions are true
fiExample:
#!/bin/bash
if [ -f /etc/hosts -a -r /etc/hosts ]; then
echo "/etc/hosts exists and is readable."
fiExplanation:
-f: Checks if it is a regular file.-r: Checks if it is readable.
Using && and || for Logical Operations
if [ condition1 ] && [ condition2 ]; then
# Commands if both conditions are true
fiExample:
#!/bin/bash
if [ -w /etc/hosts ] || [ -w /tmp ]; then
echo "Either /etc/hosts or /tmp is writable."
fiExplanation:
-w: Checks if a file is writable.||: Logical OR.
6. Negating Conditions
Using ! to Negate
if [ ! condition ]; then
# Commands if condition is false
fiExample:
#!/bin/bash
if [ ! -x /bin/ls ]; then
echo "/bin/ls is not executable."
fiExplanation:
-x: Checks if the file is executable.!: Negates the condition.
7. Case Study: File Management Script
Script:
#!/bin/bash
read -p "Enter a filename: " filename
if [ -e $filename ]; then
if [ -d $filename ]; then
echo "$filename is a directory."
elif [ -f $filename ]; then
echo "$filename is a regular file."
else
echo "$filename exists but is neither a file nor a directory."
fi
else
echo "$filename does not exist."
fi
Explanation:
- Prompts the user for a filename and checks its type using nested
ifstatements.
8. Common Condition Options
| Option | Meaning |
-e | File exists |
-f | File exists and is a regular file |
-d | Directory exists |
-r | File is readable |
-w | File is writable |
-x | File is executable |
-z | String is empty |
-n | String is not empty |
== | String comparison (equal) |
!= | String comparison (not equal) |
-lt | Numeric comparison (less than) |
-gt | Numeric comparison (greater than) |
-le | Numeric comparison (less than or equal) |
-ge | Numeric comparison (greater than or equal) |
This guide provides foundational knowledge for conditional execution in scripts, which is a key topic in RHCSA certification.
02.2 – Use Looping constructs (for, etc.) to process file, command line input
Introduction
Looping constructs in Linux scripting (e.g., for, while, until) are essential for automating tasks such as processing files, handling user inputs, and iterating over a list of arguments. These loops can handle repetitive tasks efficiently, making them crucial for the RHCSA exam.
1. Using for Loop
The for loop iterates over a list of items. It is particularly useful for processing files or command-line arguments.
Example 1: Processing Multiple Files
#!/bin/bash
# Iterate over a list of files and display their contents
for file in file1.txt file2.txt file3.txt; do
if [ -f "$file" ]; then
echo "Contents of $file:"
cat "$file"
else
echo "File $file not found!"
fi
doneExplanation:
- The
forloop iterates throughfile1.txt,file2.txt, andfile3.txt. - The
ifcondition checks if the file exists (-fflag). - If the file exists,
catis used to display its contents.
Example 2: Processing Command-Line Input
#!/bin/bash
# Process command-line arguments
for arg in "$@"; do
echo "Processing argument: $arg"
doneExplanation:
$@represents all the command-line arguments passed to the script.- The loop processes each argument individually.
2. Using while Loop
The while loop executes as long as a condition remains true. It is useful for reading files line by line or waiting for a condition.
Example 1: Reading a File Line by Line
#!/bin/bash
# Read a file line by line
while IFS= read -r line; do
echo "Line: $line"
done < input.txtExplanation:
IFS=prevents trimming of leading/trailing whitespace.read -rprevents backslash escape interpretation.< input.txtredirects the input file to thewhileloop.
Example 2: Waiting for a Condition
#!/bin/bash
# Wait until a file exists
while [ ! -f /tmp/myfile ]; do
echo "Waiting for /tmp/myfile..."
sleep 2
done
echo "/tmp/myfile is now available!"Explanation:
- The loop checks if
/tmp/myfileexists. - It waits (using
sleep 2) and rechecks until the file is found.
3. Using until Loop
The until loop is the inverse of the while loop, running until a condition becomes true.
Example 1: Create a File Until Successful
#!/bin/bash
# Try creating a file until successful
until touch /tmp/testfile 2>/dev/null; do
echo "Retrying to create /tmp/testfile..."
sleep 1
done
echo "/tmp/testfile created successfully!"Explanation:
- The loop continues if
touchfails (e.g., due to permissions). - The
2>/dev/nullsuppresses error messages.
4. Combining Loops with Command Substitution
Command substitution allows looping constructs to iterate over command output.
Example 1: Iterating Over a List of Users
#!/bin/bash
# List all users from /etc/passwd
for user in $(cut -d: -f1 /etc/passwd); do
echo "User: $user"
doneExplanation:
cut -d: -f1 /etc/passwdextracts the first field (username) from/etc/passwd.- The
forloop processes each username.
Example 2: Checking Disk Usage
#!/bin/bash
# Check disk usage of home directories
for dir in /home/*; do
du -sh "$dir"
doneExplanation:
/home/*expands to all directories in/home.du -shshows the size of each directory in human-readable format.
5. Nested Loops
Nested loops handle more complex scenarios.
Example: Processing Multiple Files in Directories
#!/bin/bash
# Check disk usage of home directories
for dir in /home/*; do
du -sh "$dir"
doneExplanation:
- The outer loop iterates over directories.
- The inner loop processes files within each directory.
6. Error Handling in Loops
Always handle errors for robust scripts.
Example: Skip Non-Readable Files
#!/bin/bash
# Read files if readable
for file in /home/*; do
if [ -r "$file" ]; then
echo "Reading: $file"
cat "$file"
else
echo "Skipping unreadable file: $file"
fi
doneExplanation:
-rchecks if the file is readable.- Unreadable files are skipped.
Practice Exercises
- Write a script to list all
.logfiles in/var/logand display their sizes. - Create a script to read numbers from a file and calculate their sum using a
whileloop. - Write a nested loop to find all empty directories in
/home.
These examples cover essential looping constructs and demonstrate their practical applications, meeting RHCSA objectives.
02.3 – Process script inputs ($1, $2, etc.)
In Linux shell scripting, arguments passed to a script from the command line can be accessed using positional parameters like $1, $2, and so on. This topic is important for creating dynamic scripts that behave based on user input.
Understanding Positional Parameters
- $0: The name of the script.
- $1, $2, …: Positional parameters representing the arguments passed to the script.
- $#: The total number of arguments passed to the script.
- $@: All the arguments passed to the script as a list.
- $*: Similar to $@, but behaves differently when quoted.
- “$@”: Each argument as a separate quoted string.
- “$*”: All arguments combined into a single quoted string.
- $?: The exit status of the last executed command.
- $$: The process ID (PID) of the current shell.
- $!: The PID of the last background process.
Examples with Explanations
1. Basic Usage Create a script example.sh:
#!/bin/bash
echo "Script Name: $0"
echo "First Argument: $1"
echo "Second Argument: $2"
echo "Total Arguments: $#"
echo "All Arguments (\$*): $*"
echo "All Arguments (\$@): $@"Run the script with arguments:
bash example.sh arg1 arg2 arg3Output:
Script Name: example.sh
First Argument: arg1
Second Argument: arg2
Total Arguments: 3
All Arguments ($*): arg1 arg2 arg3
All Arguments ($@): arg1 arg2 arg32. Loop Through All Arguments Use $@ in a loop to iterate through all arguments:
#!/bin/bash
echo "Iterating over arguments:"
for arg in "$@"; do
echo "$arg"
doneRun the script:
bash example.sh one two threeOutput:
Iterating over arguments:
one
two
three3. Difference Between $* and $@
- $*: Treats all arguments as a single string.
- $@: Treats each argument as a separate entity.
Example script:
#!/bin/bash
echo "Using \$*:"
for arg in "$*"; do
echo "$arg"
done
echo "Using \$@:"
for arg in "$@"; do
echo "$arg"
doneRun:
bash example.sh "arg1 arg2" arg3Output:
Using $*:
arg1 arg2 arg3
Using $@:
arg1 arg2
arg34. Handling a Specific Number of Arguments Ensure a script behaves correctly when a required number of arguments is passed:
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <arg1> <arg2>"
exit 1
fi
echo "Argument 1: $1"
echo "Argument 2: $2"Run:
bash example.sh arg1Output:
Usage: example.sh <arg1> <arg2>Run:
bash example.sh arg1 arg2Output:
Argument 1: arg1
Argument 2: arg25. Pass Inputs to Perform Arithmetic Pass numerical arguments and use them for calculations:
#!/bin/bash
if [ "$#" -lt 2 ]; then
echo "Usage: $0 <num1> <num2>"
exit 1
fi
num1=$1
num2=$2
sum=$((num1 + num2))
echo "Sum of $num1 and $num2 is: $sum"Run:
bash example.sh 10 20Output:
Sum of 10 and 20 is: 306. Debugging with $? Check the success or failure of a command:
#!/bin/bash
cp $1 $2
if [ "$?" -eq 0 ]; then
echo "File copied successfully."
else
echo "Failed to copy file."
fiRun:
bash example.sh source.txt destination.txtOutput (if source.txt exists):
File copied successfully.Key Points for RHCSA Exam
- Understand how to access and use positional parameters.
- Use $# to validate the number of arguments passed.
- Loop through $@ for processing multiple inputs.
- Handle error conditions using $?.
- Write scripts that adapt dynamically based on inputs.
This knowledge is foundational for automating tasks in Linux, a critical skill for RHCSA certification.
02.4 – Processing output of shell commands within a script
Shell scripting involves using the output of commands as inputs to other commands or processes. This is a critical skill for automating tasks and writing efficient scripts. Here are detailed notes and examples for processing the output of shell commands.
1. Using Command Substitution
Command substitution allows you to capture the output of a shell command and use it as a variable or as input to another command.
Syntax:
- Backticks:
`command` - $() Syntax:
$(command)
Example 1: Assigning Command Output to a Variable
#!/bin/bash
# Capture the current date
current_date=$(date)
# Print the date
echo "Today's date is: $current_date"
Example 2: Using Output in a Command
#!/bin/bash
# Find the total number of files in /tmp
file_count=$(ls /tmp | wc -l)
# Display the result
echo "Number of files in /tmp: $file_count"2. Using Piping (|) to Process Output
Piping sends the output of one command to another command for further processing.
Example: Find the Largest File in a Directory
#!/bin/bash
# Find the largest file in the /var directory
largest_file=$(du -ah /var | sort -rh | head -n 1)
# Display the largest file
echo "The largest file in /var is: $largest_file"
3. Reading Command Output Line by Line
You can process command output line by line using a while loop.
Example: List Users and Their Home Directories
#!/bin/bash
# Get user information from /etc/passwd
cat /etc/passwd | while IFS=: read -r username _ _ _ _ home_dir _
do
echo "User: $username, Home Directory: $home_dir"
done4. Using read with Command Substitution
The read command can directly capture the output of a command.
Example: Capturing Hostname
#!/bin/bash
# Read the hostname into a variable
read hostname < <(hostname)
echo "The hostname of this machine is: $hostname"5. Using Process Substitution
Process substitution allows you to use the output of a command as a file input.
Example: Compare Two Command Outputs
#!/bin/bash
# Compare the list of files in two directories
diff <(ls /dir1) <(ls /dir2)6. Parsing Output with awk and sed
Use awk and sed for advanced processing of command output.
Example: Extract Specific Columns with awk
#!/bin/bash
# Get disk usage and print the mount point
df -h | awk '{print $1, $6}'
Example: Modify Text with sed
#!/bin/bash
# Replace 'root' with 'admin' in /etc/passwd output
cat /etc/passwd | sed 's/root/admin/g'7. Using Arrays to Process Multiple Outputs
You can store the output of a command in an array for further processing.
Example: Storing Directory Contents
#!/bin/bash
# Store the contents of /tmp in an array
files=($(ls /tmp))
# Loop through the array
for file in "${files[@]}"; do
echo "File: $file"
done8. Error Handling for Commands
Always handle errors when processing command outputs to make scripts robust.
Example: Check if a Command Fails
#!/bin/bash
# Try to list a non-existent directory
output=$(ls /nonexistent 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Failed to list directory"
else
echo "Directory contents: $output"
fiBest Practices
- Use
$()for command substitution: It is more readable and supports nesting. - Escape special characters: Handle filenames or outputs with special characters using quotes.
- Redirect errors: Use
2>/dev/nullto suppress errors or2>&1to redirect errors to standard output. - Validate outputs: Always check the exit status (
$?) of commands.
These techniques enable efficient processing of command outputs, a key skill for RHCSA and system administration tasks.
Discover more from Altgr Blog
Subscribe to get the latest posts sent to your email.
