0% found this document useful (0 votes)
5 views25 pages

Intermediate Shell Scripting Guide

This document provides an overview of advanced shell scripting concepts, including exit statuses, variable scopes, functions, case statements, loops, debugging techniques, and the use of sed for text manipulation. It emphasizes the importance of error handling, variable management, and script organization for effective automation. The content is structured with examples and best practices to enhance understanding of shell scripting in a Linux environment.

Uploaded by

Đạt Trịnh
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views25 pages

Intermediate Shell Scripting Guide

This document provides an overview of advanced shell scripting concepts, including exit statuses, variable scopes, functions, case statements, loops, debugging techniques, and the use of sed for text manipulation. It emphasizes the importance of error handling, variable management, and script organization for effective automation. The content is structured with examples and best practices to enhance understanding of shell scripting in a Linux environment.

Uploaded by

Đạt Trịnh
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

SHELL SCRIPTING PART 2

BY NAVEED
1. EXIT STATUS: THE CONCEPT

In Linux, every single command returns a hidden number called the Exit Status (or Return Code) when it finishes.
This integer ranges from 0 to 255.

0 represents Success.

Non-Zero 1255 represents various types of Failure.

The shell stores the exit status of the last executed command in the special variable $?.

Checking $? immediately is crucial for error handling in automation.

02 / 25 By
Naveed
EXIT STATUS: SUCCESS EXAMPLE

Let's see what happens when a command runs


successfully. [Link]
Here, ls /tmp is a valid command (assuming /tmp
exists). # Run a valid command
ls /tmp > /dev/null
We redirect output to /dev/null to keep the terminal
clean. # Check the exit status
echo "Exit Status: $?"
We immediately echo $? to see the result.

The result 0 confirms the command worked


perfectly.

03 / 25 By
Naveed
EXIT STATUS: FAILURE EXAMPLE

[Link]
Now, let's force an error to see a non-zero code.
The false command in Linux does nothing but return
false # Built-in command to fail
an exit code of 1. echo "False Status: $?"

Similarly, trying to ls a file that doesn't exist returns 2


ls /non/existent/file
No such file or directory). echo "LS Error Status: $?"

Scripts use these codes to decide whether to stop or


retry.

04 / 25 By
Naveed
CUSTOM EXIT CODES

You can manually set the exit code of your own script
custom_exit.sh
using the exit command.
If your script encounters a critical error (like missing if [ -z "$1" ]; then echo "Error: No name
arguments), use exit 1 (or any number > 0. provided!" exit 2 # Custom error code fi
echo "Hello $1" exit 0 # Success
This tells the parent process (or user) that your script
failed.

Always end a successful script with exit 0 (though


it's often implied).

05 / 25 By
Naveed
2. VARIABLES: GLOBAL SCOPE

[Link]

By default, all variables in Bash are Global. MY_VAR="Original"

If you define a variable anywhere in the script (even


change_it() {
inside a function), it is visible and modifiable by the MY_VAR="Changed!"
}
entire script.
This can cause bugs if different functions try to use
change_it
the same variable name (like i or count). echo "$MY_VAR"

06 / By
25 Naveed
VARIABLES: LOCAL SCOPE

[Link]

To prevent side effects, use the local keyword inside


my_func() {
functions.
local temp="Invisible outside"
local var=value creates a variable that exists only
echo "Inside: $temp"
within that function. }
It shadows any global variable with the same name.
my_func
Once the function finishes, the local variable is echo "Outside: $temp"

destroyed, and the global one remains untouched.

07 / By
25 Naveed
VARIABLE SCOPE COLLISION

[Link]

This example proves why local is a best practice. NAME="Naveed"


We have a global NAME "Naveed". test_scope() {
local NAME="Guest"
The function defines a local NAME "Guest". echo "In Func: $NAME"
}
Inside the function, it sees "Guest".

After the function, the global "Naveed" is perfectly test_scope


echo "Global: $NAME"
preserved.

08 / 25 By
Naveed
3. FUNCTIONS: DEFINITION

Functions allow you to group commands into a reusable [Link]

block.
Syntax: name() { commands... } # Definition
welcome() {
You can also use the keyword function name { ... }. echo "Welcome to DevOps!"
echo "Let's script."
}
Important: You do NOT put parentheses () when
# Invocation (No parentheses!)
calling the function, only when defining it.
welcome
Define functions at the top of your script before you
call them.

09 / 25 By
Naveed
FUNCTIONS: ARGUMENTS

[Link]

Functions have their own set of Positional Parameters.


Inside a function, $1 is the first argument passed to greet() {
# $1 is the first argument
the function, not the script. echo "Hello, $1!"
$2 is the second argument, and so on. }

$# is the number of arguments passed to the # Pass "Naveed" as argument


greet "Naveed"
function.
greet "World"
This allows functions to be dynamic and reusable.

10 / By
25 Naveed
FUNCTIONS: RETURN STATUS

return_code.sh

The return keyword in a function sets the Exit Status is_valid_user() {


0255. if [ "$1" == "Naveed" ]; then
It does NOT return a value/string like Python or return 0 # Success
else
JavaScript. return 1 # Failure
It is used to indicate Success 0) or Failure fi
}
(non-zero).

You capture it with $? immediately after the function is_valid_user "Bob"


echo "Result: $?"
call.

11 / By
25 Naveed
FUNCTIONS: RETURN OUTPUT

return_val.sh

To get data (strings/numbers) out of a function, you


get_time() {
must echo it to standard output. date +%H:%M
The caller captures this output using Command }
Substitution: $(function_name).
# Capture output into variable
This assigns everything the function printed to the NOW=$(get_time)
variable.
echo "Current time is $NOW"
This is the standard way to "return" values in Bash.

12 / By
25 Naveed
4. CASE STATEMENT

[Link]

The case statement is a cleaner alternative to multiple case "$VAR" in "pattern1") # Commands for
pattern1 ;; "pattern2") # Commands for pattern2
if-elif-else blocks.
It matches a variable against several patterns. ;; *) # Default commands ;; esac

Syntax ends with esac (case spelled backwards).

Each pattern block ends with double semicolons ;;.

*) acts as the "default" or "else" catch-all block.

13 / By
25 Naveed
CASE STATEMENT EXAMPLE

Here is a real-world example: Handling command-line [Link]

arguments to start or stop a service.


case "$1" in
We check the value of $1.
start) echo "Starting app..." ;;
We handle "start", "stop", and "restart". stop) echo "Stopping app..." ;;
restart) echo "Restarting..." ;;
Any other input triggers the Usage message. *) echo "Usage: $0 {start|stop}" ;;
esac
This pattern is used in almost every system init
script.

14 / By
25 Naveed
5. LOOPS: FOR LOOP (LIST)

The classic for loop iterates over a list of items. for_list.sh

Useful for processing a list of strings, filenames, or


# Iterate over explicit strings
server names. for fruit in Apple Banana Cherry; do
The variable item takes the value of each element in echo "I like $fruit"
done
the list one by one.

You can perform the same operation on every item.

15 / By
25 Naveed
LOOPS: FOR LOOP (C-STYLE)

Bash supports C-style loops for numeric iteration. c_style.sh

Syntax: (( initial; condition; increment )).


# Count from 1 to 3
Best used when you need a specific number of for (( i=1; i<=3; i++ )); do
echo "Counter: $i"
iterations or an index counter.
done
Note the double parentheses (( )) which are specific
to Bash arithmetic.

16 / By
25 Naveed
LOOPS: WHILE LOOP

The while loop continues running as long as the [Link]

condition is True.
Useful for reading files line-by-line. count=1
while [ $count -le 3 ]; do
Useful for creating "daemon" scripts that run forever echo "Count: $count"
count=$((count + 1))
(while true).
done
Remember to update the condition variable (like
count) to avoid infinite loops!

17 / By
25 Naveed
LOOPS: UNTIL LOOP

[Link]

The until loop is the opposite of while.


It runs until the condition becomes True. count=1
# Run UNTIL count > 3
In other words, it runs as long as the condition is until [ $count -gt 3 ]; do
echo "Wait: $count"
False.
count=$((count + 1))
Great for waiting for a resource to become available done

(like waiting for a server to ping).

18 / By
25 Naveed
LOOPS: SELECT (MENUS)

[Link]

select allows you to create interactive menus easily. PS3="Choose: "


select opt in Run Quit; do
It automatically prints a numbered list of options.
case $opt in
It prompts the user to enter a number. Run) echo "Running..." ;;
Quit) break ;;
Often combined with case to handle the choice. *) echo "Invalid" ;;
esac
Set PS3 to change the prompt string. done

19 / By
25 Naveed
6. DEBUGGING OVERVIEW

Scripts will fail. Debugging is about finding out why and where.
Trace Mode: Prints commands before executing them.

Exit on Error: Stops script immediately if a command fails.

Syntax Check: Checks code without running it.

Linting: Use external tools like shellcheck.

20 / 25 By
Naveed
DEBUGGING: SET MODES

debug_modes.sh

The set command controls shell options. # Enable trace & exit on error
set -x (xtrace): Prints each command to stderr before set -xe

execution. Great for tracing logic.


NAME="Naveed"
set -e (errexit): Aborts script if any command returns echo "Hello $NAME"

a non-zero exit status.


ls /nonexistent # Script dies here
set -u (nounset): Treats unset variables as an error echo "This won't run"

(prevents "rm -rf /" disasters).

21 / By
25 Naveed
DEBUGGING: TRAP

trap allows you to catch signals and errors to perform [Link]

cleanup.
trap 'echo "Error at line $LINENO!"' ERR
Catch ERR to run code when a command fails.

Catch EXIT to run code when the script finishes echo "Running..."
ls /missing_file
(successfully or not).
echo "Done"
Commonly used to remove temporary files or log
errors.

22 / 25 By
Naveed
7. SED (STREAM EDITOR)

sed is a powerful tool for parsing and transforming text


in a stream (file or pipeline).
Most common use: Find and Replace.
basic_sed.sh

Basic Syntax: s/search_pattern/replacement/flags.


echo "Hello World" | sed 's/World/Naveed/'
By default, it prints the modified text to the screen
Standard Output).

It does not modify the original file unless you use a


specific flag.

23 / 25 By
Naveed
SED: INLINE EDIT & DELETION

advanced_sed.sh
-i: Edit file In-place (save changes to file).
# Replace OLD with NEW in file sed -i
d: Delete matching lines.
's/OLD/NEW/g' [Link]
# Delete lines containing "error" sed -i
Warning: -i is destructive. Test your regex without it
'/error/d' [Link]
first!

24 / 25 By
Naveed
THANKS FOR READING! 🙏
You've leveled up to Intermediate Shell Scripting.

Follow Naveed Ibrahim A for more daily


DevOps bites.

Snail Cooked By Naveed | DevOps & Cloud


Learner

You might also like