Fundamentals of Shell Scripting in Linux
Understanding Shell Scripting
Shell scripting is essential for server management tasks, allowing developers to automate operations and interact with the Linux kernel through a command-line interpreter. Shell scripts enable users to start, stop, or manage programs efficiently.
Creating and Executing Shell Scripts
Shell scripts require two key elements: a shebang line starting with #!/bin/bash and executable permissions. Follow these steps to create your first script:
- Create a directory for storing scripts:
mkdir ~/scripts
cd ~/scripts
- Create a new script file using a text editor:
#!/bin/bash
echo "Welcome to shell scripting"
- Check the script's permissions:
ls -l script.sh
- Add execute permissions:
chmod u+x script.sh
Common execution methods include:
- Using the script's absolute or relative path (requires execute permission)
- Using
sh script.sh(doesn't require execute permission)
Variables in Shell Scripting
System and User-Defined Variables
Shell variables are categorized as system variables (predefined) and user-defined variables. Common system variables include $HOME, $PWD, $USER, and $SHELL. Use the set command to view all system variables.
User-defined variable syntax:
# Define variable
VAR_NAME=value
# Unset variable
unset VAR_NAME
# Define read-only variable
readonly CONSTANT=value
# Output variable
echo $VAR_NAME
Example operations:
# Define variable
COUNTER=100
# Output variable
echo COUNTER=$COUNTER
echo "COUNTER=$COUNTER"
# Unset variable
unset COUNTER
echo $COUNTER
# Define read-only variable
readonly MAX_VALUE=3
echo $MAX_VALUE
Variable Naming Rules
Variable names can contain letters, numbers, and underscores, but cannot start with a number. No spaces are allowed around the equals sign. Variable name are typical uppercase.
Too assign command output to variables:
# Using backticks
RESULT=`date`
# Using $() syntax
RESULT=$(date)
Environment Variables
export VAR_NAME=value # Make variable global
source config_file # Apply configuration changes immediately
echo $VAR_NAME # Check variable value
Example: Define TOMCAT_HOME in /etc/profile:
export TOMCAT_HOME=/opt/tomcat
source /etc/profile
Posisional Parameters
Positional parameters capture command-line arguments:
$0 # Script name
$1-$9 # First nine parameters
${10} # Tenth parameter (requires braces)
$* # All parameters as a single string
$@ # All parameters as separate strings
$# # Number of parameters
Example script params.sh:
#!/bin/bash
echo "Script: $0, First: $1, Second: $2"
echo "All params: $*"
echo "Param count: $#"
Special Variables
$$ # Current process ID (PID)
$! # PID of last background process
$? # Exit status of last command (0 = success)
Operators
Shell supports arithmetic operations using $((expression)), $[expression], or expr:
* # Multiplication (use \* in backticks)
/ # Division
% # Modulus
Example: Calculate (2+3)×4:
#!/bin/bash
# Method 1
result1=$(((2+3)*4))
echo "Result 1: $result1"
# Method 2
result2=$[(2+3)*4]
echo "Result 2: $result2"
# Method 3
temp=`expr 2 + 3`
result3=`expr $temp \* 4`
echo "Result 3: $result3"
Example: Sum two command-line arguments:
sum=$[$1+$2]
echo "Sum: $sum"
Conditional Statements
Conditional expressions use [ condition ] syntax (note spaces around brackets). Use $? to check results (0 = true, non-zero = false).
[ "test" ] && echo "yes" || echo "no"
Common comparison operators:
# String comparison
= # Equal
# Integer comparison
-lt # Less than
-le # Less than or equal
-eq # Equal
-gt # Greater than
-ge # Greater than or equal
-ne # Not equal
# File permissions
-r # Readable
-w # Writable
-x # Executable
# File types
-f # Regular file exists
-e # File exists
-d # Directory exists
Examples:
#!/bin/bash
# String comparison
if [ "hello" = "hello" ]
then
echo "Strings match"
fi
# Integer comparison
if [ 22 -ge 21 ]
then
echo "Greater than or equal"
fi
# File check
if [ -f ~/scripts/test.txt ]
then
echo "File exists"
fi
Flow Control
If Statements
# Single condition
if [ condition ]
then
commands
fi
# Multiple conditions
if [ condition1 ]
then
commands
elif [ condition2 ]
then
commands
fi
Example: Check if score is passing:
#!/bin/bash
if [ $1 -ge 60 ]
then
echo "Pass"
elif [ $1 -lt 60 ]
then
echo "Fail"
fi
Case Statements
case $variable in
"value1")
commands
;;
"value2")
commands
;;
*)
default commands
;;
esac
Example: Day of week:
#!/bin/bash
case $1 in
"1")
echo "Monday"
;;
"2")
echo "Tuesday"
;;
*)
echo "Other day"
;;
esac
For Loops
Syntax 1:
for item in value1 value2 value3
do
commands
done
Example with positional parameters:
#!/bin/bash
# Using $*
for param in "$*"
do
echo "Parameter: $param"
done
# Using $@
for param in "$@"
do
echo "Parameter: $param"
done
Syntax 2:
for ((initialization; condition; increment))
do
commands
done
Example: Sum numbers 1 to 100:
#!/bin/bash
total=0
for ((i=1; i<=100; i++))
do
total=$[$total+$i]
done
echo "Total: $total"
While Loops
while [ condition ]
do
commands
done
Example: Sum numbers up to n:
#!/bin/bash
sum=0
counter=0
while [ $counter -le $1 ]
do
sum=$[$sum+$counter]
counter=$[$counter+1]
done
echo "Sum: $sum"
Reading User Input
The read command captures console input:
read [options] variable
-p "prompt" # Display prompt
-t seconds # Timeout duration
Examples:
#!/bin/bash
# Basic input
read -p "Enter number: " num
echo "You entered: $num"
# Input with timeout
read -t 10 -p "Enter number within 10 seconds: " num2
echo "You entered: $num2"
Functions
Function definition:
function_name() {
commands
echo "Argument: $1"
}
# Alternative syntax
function function_name {
commands
}
Functon call:
param="example"
function_name $param
Return Values
Shell functions return exit status (0-255). To capture output:
my_function() {
local result="output value"
echo $result
}
value=$(my_function)
Using return for success/failure:
my_function() {
# Perform operations
return 0 # Success
}
if my_function; then
echo "Success"
else
echo "Failure"
fi
Comments
Single-line comments use #:
#!/bin/bash
# This is a comment
echo "Script running"
Multi-line comments:
: '
This is a
multi-line
comment
'
:<<END
Another way to
create multi-line
comments
END
Logging Output
Redirect output to files:
# Redirect stdout to file
./script.sh > output.log
# Redirect both stdout and stderr
./script.sh > output.log 2>&1
# Output to console and file
./script.sh | tee output.log
Script Execution Methods
./script.sh # Direct execution
sh script.sh # Execute in subshell
sh -x script.sh # Debug mode (trace execution)
source script.sh # Execute in current shell
. script.sh # Same as source
Exit Codes
Exit codes indicate script success (0) or failure (non-zero):
#!/bin/bash
check_args() {
if [ $# -lt 2 ]
then
echo "Insufficient arguments"
exit 1
fi
echo "Valid arguments"
exit 0
}
if [ $# -lt 1 ]
then
echo "No arguments provided"
exit 1
fi
result=$(check_args "$@")
echo "Script completed"
exit 0