05. Control Structures in Shell Scripting
π Master shell scripting control flow! Learn conditional statements, loops, case statements, and more to build powerful and efficient scripts. π‘
What we will learn in this post?
- π Conditional Statements in Shell
- π Looping in Shell
- π Using Case Statements
- π Break and Continue in Loops
- π Combining Multiple Conditions in Shell
- π Conclusion!
Conditional Statements in Python: if
, if-else
, elif
Conditional statements control the flow of your code based on whether a condition is true or false. Letβs explore them!
The if
Statement π¨βπ»
The simplest form checks a single condition.
1
2
3
import os
if os.path.exists("my_file.txt"): #checks if file exists
print("File exists!")
Example: Numerical Comparison
1
2
3
x = 10
if x > 5:
print("x is greater than 5")
The if-else
Statement βοΈ
This handles two possibilities: true or false.
1
2
3
4
5
age = 15
if age >= 18:
print("You can vote!")
else:
print("You are too young to vote.")
The elif
Statement π
Handles multiple conditions sequentially. Itβs like saying, βif the first condition is false, then check this one, and then this oneβ¦β
1
2
3
4
5
6
7
8
9
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
else:
print("F")
More Info: For a deeper dive, check out the official Python documentation on conditional statements.
Note: Remember indentation is crucial in Python! Incorrect indentation will lead to errors. Use 4 spaces for consistent and readable code.
Shell Scripting Loops π
Shell scripts use loops to repeat commands. Letβs explore for
, while
, and until
loops!
Loop Types π
for
loop: Iterates over a list of items. Example: iterating through files in a directory:1
for file in *.txt; do echo "$file"; done
while
loop: Repeats as long as a condition is true. Example: prompting for user input until a specific value is entered:1
while [[ "$input" != "quit" ]]; do read -p "Enter input (or 'quit'): " input; done
until
loop: Repeats until a condition becomes true (opposite ofwhile
). Example: repeating a task until a file exists:1
until [ -f "myfile.txt" ]; do echo "Waiting for myfile.txt..."; sleep 1; done
Numerical Ranges with for
You can also use for
loops with numerical ranges using brace expansion or seq
:
1
for i in {1..5}; do echo "$i"; done #Prints 1 to 5
Applications π
Loops are useful for:
- File processing: Processing multiple files, like converting images or extracting data.
- User interaction: Creating interactive scripts that repeatedly ask for input.
- Automation: Automating repetitive tasks, such as backups or system checks.
More Info: For a deeper dive, explore the Bash manual. Remember to always test your scripts carefully! π
Shell Scriptingβs case
Statements: A Simpler Way
Understanding case
Statements β¨
The case
statement in shell scripts is like a super-charged if-else if-else
structure. It elegantly handles multiple conditions based on a single variableβs value. Think of it as a powerful switch for your scriptβs logic!
Simple Example: A Menu
1
2
3
4
5
6
7
read -p "Enter choice (1-3): " choice
case $choice in
1) echo "You chose option 1";;
2) echo "You chose option 2";;
3) echo "You chose option 3";;
*) echo "Invalid choice";;
esac
This script presents a menu and uses case
to execute different commands based on user input. *)
acts as a default case for invalid input.
More Advanced Uses π
- User Input Handling: Validate user input easily. Check for specific values or patterns.
- Process Control: Decide what actions to take based on the outcome of other commands or events.
Example: Process Control
1
2
3
4
5
6
status=$? #Check the exit status of a previous command
case $status in
0) echo "Command succeeded!";;
1) echo "Command failed!";;
*) echo "Something unexpected happened!";;
esac
Flowchart:
graph TD
A["β¨οΈ Read User Input"] --> B{"π Case Statement"};
B -- π
° Choice 1 --> C["β
Execute Option 1"];
B -- π
± Choice 2 --> D["β
Execute Option 2"];
B -- π
Ύ Choice 3 --> E["β
Execute Option 3"];
B -- β Default --> F["β οΈ Invalid Choice"];
C --> G["π End"];
D --> G;
E --> G;
F --> G;
%% Custom Styles
classDef inputStyle fill:#FFD700,stroke:#B8860B,color:#000000,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef caseStyle fill:#1E90FF,stroke:#00008B,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef optionStyle fill:#32CD32,stroke:#006400,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef invalidStyle fill:#FF6347,stroke:#B22222,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef endStyle fill:#8A2BE2,stroke:#4B0082,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
%% Apply Classes
class A inputStyle;
class B caseStyle;
class C,D,E optionStyle;
class F invalidStyle;
class G endStyle;
For more information, explore these resources: Bash Guide, Advanced Bash Scripting Guide
Using case
makes your shell scripts cleaner, more readable, and easier to maintain, especially when dealing with many conditional branches. Itβs a fundamental tool for any shell scripting enthusiast! π
Controlling Loops with break
and continue
in Shell Scripting π
Shell scripting offers break
and continue
statements to manage loop flow. These are invaluable for handling situations where you need to adjust loop behavior based on certain conditions.
The break
Statement π₯
The break
statement immediately terminates the loop itβs inside. Execution continues with the statement after the loop.
Example:
1
2
3
4
5
6
for i in {1..10}; do
if [ $i -eq 5 ]; then
break # Exit loop when i equals 5
fi
echo $i
done
This loop will print numbers 1 through 4, then stop.
The continue
Statement β©
continue
skips the rest of the current iteration and proceeds to the next iteration of the loop.
Example:
1
2
3
4
5
6
for i in {1..10}; do
if [ $((i % 2)) -eq 0 ]; then
continue # Skip even numbers
fi
echo $i
done
This loop prints only odd numbers (1, 3, 5, 7, 9).
Visualizing the Difference π€
graph TD
A["π Start Loop"] --> B{"β Condition?"};
B -- β
True --> C["βΉοΈ Break"];
B -- β False --> D["π Process Iteration"];
D --> E["β‘οΈ Next Iteration"];
C --> F["π End Loop"];
E --> B;
%% Custom Styles
classDef loopStyle fill:#FFD700,stroke:#B8860B,color:#000000,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef conditionStyle fill:#1E90FF,stroke:#00008B,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef processStyle fill:#32CD32,stroke:#006400,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef breakStyle fill:#FF6347,stroke:#B22222,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef endStyle fill:#8A2BE2,stroke:#4B0082,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
%% Apply Classes
class A loopStyle;
class B conditionStyle;
class C breakStyle;
class D,E processStyle;
class F endStyle;
graph TD
A["π Start Loop"] --> B{"β Condition?"};
B -- β
True --> C["β‘οΈ Continue"];
B -- β False --> D["π Process Iteration"];
D --> E["β‘οΈ Next Iteration"];
C --> E;
E --> B;
%% Custom Styles
classDef loopStyle fill:#FFD700,stroke:#B8860B,color:#000000,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef conditionStyle fill:#1E90FF,stroke:#00008B,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef processStyle fill:#32CD32,stroke:#006400,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
classDef continueStyle fill:#FF8C00,stroke:#FF4500,color:#FFFFFF,font-size:14px,stroke-width:3px,rx:15px,shadow:5px;
%% Apply Classes
class A loopStyle;
class B conditionStyle;
class C continueStyle;
class D,E processStyle;
(Note: These diagrams illustrate the flow; the exact implementation in shell scripting might vary slightly.)
Remember: These statements significantly improve the readability and efficiency of your shell scripts by allowing fine-grained control over looping. Use them wisely to create cleaner and more robust code!
Logical Operators in Shell Scripts π€
Shell scripts often need to check multiple conditions. This is where logical operators shine!
AND (&&
) and OR (||
)
&&
(AND): This operator executes the second command only if the first command succeeds (exits with a status code of 0). Think of it as βboth conditions must be trueβ.||
(OR): This operator executes the second command only if the first command fails (exits with a non-zero status code). Think of it as βat least one condition must be trueβ.
Examples
Letβs say you want to check if a file exists and is writable:
1
[ -f myfile.txt ] && [ -w myfile.txt ] && echo "File exists and is writable" || echo "File problem!"
This first checks if myfile.txt
exists (-f
), then if itβs writable (-w
). Only if both are true, it prints the success message. Otherwise, the error message shows up.
Another example: Back up a file only if itβs modified since the last backup or itβs larger than 1GB:
1
[ $(stat -c %Y myfile.txt) -gt $(stat -c %Y backup.txt) ] || [ $(stat -c %s myfile.txt) -gt 1073741824 ] && cp myfile.txt backup.txt
This checks file modification time and size before creating a backup.
Remember: 0
means success, any other number means failure in shell return codes.
Conclusion
And thatβs a wrap! We hope you enjoyed this post. Weβd love to hear your thoughts β what did you think? Any questions or suggestions? Let us know in the comments below! π Happy chatting! π