Merge pull request #21 from SCAR-iT-COLO/14-sanitize-chapter-7
Sanitize Chapter 7
This commit is contained in:
commit
a7c7e19eac
@ -7,41 +7,41 @@ Loops are fundamental constructs in programming that allow you to execute a set
|
||||
The 'for' loop is used to iterate over a list of items or a range of values.
|
||||
|
||||
Syntax:
|
||||
```bash
|
||||
```
|
||||
for variable in list
|
||||
do
|
||||
commands
|
||||
commands
|
||||
done
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
- Iterating over a list of items:
|
||||
```bash
|
||||
```
|
||||
for fruit in apple banana orange
|
||||
do
|
||||
echo "I like $fruit"
|
||||
echo "I like $fruit"
|
||||
done
|
||||
```
|
||||
|
||||
- Iterating over a range of numbers:
|
||||
```bash
|
||||
for i in {1..5}
|
||||
```
|
||||
for i in {1..5} #{1..5} is using brace expansion for everything in the range of 1-5
|
||||
do
|
||||
echo "Number: $i"
|
||||
echo "Number: $i"
|
||||
done
|
||||
```
|
||||
|
||||
- C-style for loop:
|
||||
```bash
|
||||
```
|
||||
for ((i=0; i<5; i++))
|
||||
do
|
||||
echo "Count: $i"
|
||||
echo "Count: $i"
|
||||
done
|
||||
```
|
||||
|
||||
- Iterating over files in a directory:
|
||||
```bash
|
||||
```
|
||||
for file in *.txt
|
||||
do
|
||||
echo "Processing $file"
|
||||
@ -54,34 +54,34 @@ done
|
||||
The 'while' loop executes a set of commands as long as a given condition is true.
|
||||
|
||||
Syntax:
|
||||
```bash
|
||||
```
|
||||
while condition
|
||||
do
|
||||
commands
|
||||
commands
|
||||
done
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
- Basic while loop:
|
||||
```bash
|
||||
```
|
||||
count=1
|
||||
while [ $count -le 5 ]
|
||||
while [ $count -le 5 ] # -le is less than or equal to
|
||||
do
|
||||
echo "Count: $count"
|
||||
((count++))
|
||||
echo "Count: $count"
|
||||
((count++))
|
||||
done
|
||||
```
|
||||
|
||||
- Reading input until a condition is met:
|
||||
```bash
|
||||
while read -p "Enter a number (0 to exit): " num
|
||||
```
|
||||
while read -p "Enter a number (0 to exit): " num # the read command takes user input and stores it as a variable
|
||||
do
|
||||
if [ "$num" -eq 0 ]; then
|
||||
echo "Exiting..."
|
||||
break
|
||||
fi
|
||||
echo "You entered: $num"
|
||||
if [ "$num" -eq 0 ]; then
|
||||
echo "Exiting..."
|
||||
break
|
||||
fi
|
||||
echo "You entered: $num"
|
||||
done
|
||||
```
|
||||
|
||||
@ -90,21 +90,21 @@ done
|
||||
The 'until' loop is similar to the while loop, but it executes commands until a condition becomes true.
|
||||
|
||||
Syntax:
|
||||
```bash
|
||||
```
|
||||
until condition
|
||||
do
|
||||
commands
|
||||
commands
|
||||
done
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
count=1
|
||||
until [ $count -gt 5 ]
|
||||
do
|
||||
echo "Count: $count"
|
||||
((count++))
|
||||
echo "Count: $count"
|
||||
((count++))
|
||||
done
|
||||
```
|
||||
|
||||
@ -116,67 +116,67 @@ Bash provides two main loop control statements:
|
||||
- continue: Skips the rest of the current iteration and moves to the next one
|
||||
|
||||
Example using both:
|
||||
```bash
|
||||
```
|
||||
for i in {1..10}
|
||||
do
|
||||
if [ $i -eq 5 ]; then
|
||||
continue
|
||||
fi
|
||||
if [ $i -eq 8 ]; then
|
||||
break
|
||||
fi
|
||||
echo "Number: $i"
|
||||
if [ $i -eq 5 ]; then
|
||||
continue
|
||||
fi
|
||||
if [ $i -eq 8 ]; then
|
||||
break
|
||||
fi
|
||||
echo "Number: $i"
|
||||
done
|
||||
```
|
||||
|
||||
## 5. Advanced Loop Techniques
|
||||
|
||||
- Nested loops:
|
||||
```bash
|
||||
```
|
||||
for i in {1..3}
|
||||
do
|
||||
for j in {1..3}
|
||||
do
|
||||
echo "i=$i, j=$j"
|
||||
done
|
||||
for j in {1..3}
|
||||
do
|
||||
echo "i=$i, j=$j"
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
- Looping through arrays:
|
||||
```bash
|
||||
```
|
||||
declare -a fruits=("apple" "banana" "orange" "grape")
|
||||
for fruit in "${fruits[@]}"
|
||||
do
|
||||
echo "I like $fruit"
|
||||
echo "I like $fruit"
|
||||
done
|
||||
```
|
||||
|
||||
- Infinite loops (use with caution):
|
||||
```bash
|
||||
while true
|
||||
```
|
||||
while true # the "true" command always returns TRUE -so this will loop forever!
|
||||
do
|
||||
echo "This will run forever unless interrupted"
|
||||
sleep 1
|
||||
echo "This will run forever unless interrupted"
|
||||
sleep 1
|
||||
done
|
||||
```
|
||||
|
||||
- Looping with command substitution:
|
||||
```bash
|
||||
for line in $(cat file.txt)
|
||||
```
|
||||
for line in $(cat file.txt) # $() is command substitution - you can put a command in here and the output will be used!
|
||||
do
|
||||
echo "Line: $line"
|
||||
echo "Line: $line"
|
||||
done
|
||||
```
|
||||
|
||||
- Parallel execution of loops:
|
||||
```bash
|
||||
```
|
||||
for job in job1 job2 job3
|
||||
do
|
||||
(
|
||||
echo "Starting $job"
|
||||
sleep 2
|
||||
echo "Finished $job"
|
||||
) &
|
||||
(
|
||||
echo "Starting $job"
|
||||
sleep 2
|
||||
echo "Finished $job"
|
||||
) &
|
||||
done
|
||||
wait
|
||||
echo "All jobs completed"
|
||||
|
||||
@ -7,7 +7,7 @@ Bash (Bourne Again SHell) is a command-line interface and scripting language use
|
||||
To create a Bash script:
|
||||
|
||||
- Open a text editor
|
||||
- Start the file with a shebang: #!/bin/bash
|
||||
- Start the file with a shebang: #!/bin/bash # This line tells the shell what to use as the interpreter. Can be bash, python, etc...
|
||||
- Add your commands
|
||||
- Save the file with a .sh extension (e.g., myscript.sh)
|
||||
- Make the script executable: chmod +x myscript.sh
|
||||
@ -23,7 +23,7 @@ echo "Hello, World!"
|
||||
|
||||
Variables in Bash are created by assigning a value:
|
||||
|
||||
```bash
|
||||
```
|
||||
name="John"
|
||||
age=30
|
||||
echo "Name: $name, Age: $age"
|
||||
@ -31,16 +31,17 @@ echo "Name: $name, Age: $age"
|
||||
|
||||
Use `$` to reference variables. For command substitution, use `$(command)`:
|
||||
|
||||
```bash
|
||||
```
|
||||
current_date=$(date +%Y-%m-%d)
|
||||
echo "Today is $current_date"
|
||||
```
|
||||
- Output: Today is 2024-09-07
|
||||
|
||||
## 3. User Input
|
||||
|
||||
Use `read` to get user input:
|
||||
|
||||
```bash
|
||||
```
|
||||
echo "What's your name?"
|
||||
read user_name
|
||||
echo "Hello, $user_name!"
|
||||
@ -50,7 +51,7 @@ echo "Hello, $user_name!"
|
||||
|
||||
If-else statements:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [ "$age" -ge 18 ]; then
|
||||
echo "You are an adult"
|
||||
else
|
||||
@ -64,21 +65,21 @@ Note the spaces around the brackets and comparison operator.
|
||||
|
||||
For loop:
|
||||
|
||||
```bash
|
||||
```
|
||||
for i in {1..5}
|
||||
do
|
||||
echo "Iteration $i"
|
||||
echo "Iteration $i"
|
||||
done
|
||||
```
|
||||
|
||||
While loop:
|
||||
|
||||
```bash
|
||||
```
|
||||
counter=1
|
||||
while [ $counter -le 5 ]
|
||||
do
|
||||
echo "Counter: $counter"
|
||||
((counter++))
|
||||
echo "Counter: $counter"
|
||||
((counter++))
|
||||
done
|
||||
```
|
||||
|
||||
@ -86,9 +87,9 @@ done
|
||||
|
||||
Define and call functions:
|
||||
|
||||
```bash
|
||||
```
|
||||
greet() {
|
||||
echo "Hello, $1!"
|
||||
echo "Hello, $1!" # $1 takes the first argument passed after the function
|
||||
}
|
||||
|
||||
greet "Alice"
|
||||
@ -99,7 +100,7 @@ greet "Bob"
|
||||
|
||||
Access command-line arguments using `$1`, `$2`, etc.:
|
||||
|
||||
```bash
|
||||
```
|
||||
echo "Script name: $0"
|
||||
echo "First argument: $1"
|
||||
echo "Second argument: $2"
|
||||
@ -110,19 +111,19 @@ echo "All arguments: $@"
|
||||
|
||||
Check if a file exists:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [ -f "myfile.txt" ]; then
|
||||
echo "myfile.txt exists"
|
||||
echo "myfile.txt exists"
|
||||
else
|
||||
echo "myfile.txt does not exist"
|
||||
echo "myfile.txt does not exist"
|
||||
fi
|
||||
```
|
||||
|
||||
Read from a file:
|
||||
|
||||
```bash
|
||||
```
|
||||
while IFS= read -r line
|
||||
do
|
||||
echo "$line"
|
||||
echo "$line"
|
||||
done < "myfile.txt"
|
||||
```
|
||||
|
||||
@ -6,21 +6,21 @@ Conditional statements in Bash allow you to control the flow of your script base
|
||||
|
||||
The most basic conditional statement is the 'if' statement. Its syntax is:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [ condition ]; then
|
||||
# commands to execute if condition is true
|
||||
# commands to execute if condition is true
|
||||
fi
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
age=18
|
||||
|
||||
if [ $age -ge 18 ]; then
|
||||
echo "You are an adult."
|
||||
echo "You are an adult."
|
||||
fi
|
||||
```
|
||||
|
||||
@ -28,25 +28,25 @@ fi
|
||||
|
||||
The if-else statement allows you to specify actions for both when the condition is true and when it's false:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [ condition ]; then
|
||||
# commands to execute if condition is true
|
||||
# commands to execute if condition is true
|
||||
else
|
||||
# commands to execute if condition is false
|
||||
# commands to execute if condition is false
|
||||
fi
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
age=16
|
||||
|
||||
if [ $age -ge 18 ]; then
|
||||
echo "You are an adult."
|
||||
echo "You are an adult."
|
||||
else
|
||||
echo "You are a minor."
|
||||
echo "You are a minor."
|
||||
fi
|
||||
```
|
||||
|
||||
@ -54,35 +54,35 @@ fi
|
||||
|
||||
For multiple conditions, use the if-elif-else structure:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [ condition1 ]; then
|
||||
# commands for condition1
|
||||
# commands for condition1
|
||||
elif [ condition2 ]; then
|
||||
# commands for condition2
|
||||
# commands for condition2
|
||||
elif [ condition3 ]; then
|
||||
# commands for condition3
|
||||
# commands for condition3
|
||||
else
|
||||
# commands if none of the conditions are true
|
||||
# commands if none of the conditions are true
|
||||
fi
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
grade=75
|
||||
|
||||
if [ $grade -ge 90 ]; then
|
||||
echo "A"
|
||||
echo "A"
|
||||
elif [ $grade -ge 80 ]; then
|
||||
echo "B"
|
||||
echo "B"
|
||||
elif [ $grade -ge 70 ]; then
|
||||
echo "C"
|
||||
echo "C"
|
||||
elif [ $grade -ge 60 ]; then
|
||||
echo "D"
|
||||
echo "D"
|
||||
else
|
||||
echo "F"
|
||||
echo "F"
|
||||
fi
|
||||
```
|
||||
|
||||
@ -102,13 +102,13 @@ String comparisons:
|
||||
- =: equal to
|
||||
- !=: not equal to
|
||||
- <: less than (in ASCII alphabetical order)
|
||||
- >: greater than (in ASCII alphabetical order)
|
||||
- \>: greater than (in ASCII alphabetical order)
|
||||
- -z: string is null (zero length)
|
||||
- -n: string is not null
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
num1=10
|
||||
@ -117,11 +117,11 @@ str1="hello"
|
||||
str2="world"
|
||||
|
||||
if [ $num1 -lt $num2 ]; then
|
||||
echo "$num1 is less than $num2"
|
||||
echo "$num1 is less than $num2"
|
||||
fi
|
||||
|
||||
if [ $str1 != $str2 ]; then
|
||||
echo "$str1 is not equal to $str2"
|
||||
echo "$str1 is not equal to $str2"
|
||||
fi
|
||||
```
|
||||
|
||||
@ -129,23 +129,23 @@ fi
|
||||
|
||||
Bash supports logical AND and OR operations:
|
||||
|
||||
- &&: AND
|
||||
- ||: OR
|
||||
- &&: AND # Double ampersand Shift+7 (qwerty)
|
||||
- ||: OR # Double Pipe | | with no spaces!
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
age=25
|
||||
has_license=true
|
||||
|
||||
if [ $age -ge 18 ] && [ "$has_license" = true ]; then
|
||||
echo "You can drive a car."
|
||||
echo "You can drive a car."
|
||||
fi
|
||||
|
||||
if [ $age -lt 18 ] || [ "$has_license" != true ]; then
|
||||
echo "You cannot drive a car."
|
||||
echo "You cannot drive a car."
|
||||
fi
|
||||
```
|
||||
|
||||
@ -153,40 +153,40 @@ fi
|
||||
|
||||
The case statement is useful when you have multiple conditions based on a single variable:
|
||||
|
||||
```bash
|
||||
```
|
||||
case $variable in
|
||||
pattern1)
|
||||
# commands for pattern1
|
||||
;;
|
||||
pattern2)
|
||||
# commands for pattern2
|
||||
;;
|
||||
*)
|
||||
# default case
|
||||
;;
|
||||
pattern1)
|
||||
# commands for pattern1
|
||||
;;
|
||||
pattern2)
|
||||
# commands for pattern2
|
||||
;;
|
||||
*) # This is the default or catch-all case
|
||||
# default case
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
fruit="apple"
|
||||
|
||||
case $fruit in
|
||||
"apple")
|
||||
echo "This is a red fruit."
|
||||
;;
|
||||
"banana")
|
||||
echo "This is a yellow fruit."
|
||||
;;
|
||||
"grape")
|
||||
"apple")
|
||||
echo "This is a red fruit."
|
||||
;;
|
||||
"banana")
|
||||
echo "This is a yellow fruit."
|
||||
;;
|
||||
"grape")
|
||||
echo "This is a purple fruit."
|
||||
;;
|
||||
*)
|
||||
echo "Unknown fruit."
|
||||
;;
|
||||
;;
|
||||
*)
|
||||
echo "Unknown fruit."
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
@ -194,15 +194,15 @@ esac
|
||||
|
||||
The test command is often used in conditional statements. It's equivalent to using square brackets []. You can use it like this:
|
||||
|
||||
```bash
|
||||
```
|
||||
if test $a -eq $b; then
|
||||
echo "a is equal to b"
|
||||
echo "a is equal to b"
|
||||
fi
|
||||
```
|
||||
|
||||
This is the same as:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [ $a -eq $b ]; then
|
||||
echo "a is equal to b"
|
||||
fi
|
||||
@ -212,24 +212,20 @@ fi
|
||||
|
||||
Bash also supports double square brackets [[ ]] for conditional tests. These provide more features than single brackets, such as pattern matching:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
string="Hello, World!"
|
||||
|
||||
if [[ $string == Hello* ]]; then
|
||||
echo "String starts with 'Hello'"
|
||||
echo "String starts with 'Hello'"
|
||||
fi
|
||||
```
|
||||
|
||||
Double brackets also allow you to use && and || inside the condition:
|
||||
|
||||
```bash
|
||||
```
|
||||
if [[ $a -eq 5 && $b -gt 10 ]]; then
|
||||
echo "Condition met"
|
||||
echo "Condition met"
|
||||
fi
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Conditional statements are crucial for creating dynamic and responsive Bash scripts. They allow your scripts to make decisions based on various conditions, making your scripts more versatile and powerful. Practice using these constructs to become proficient in Bash scripting.
|
||||
|
||||
@ -8,19 +8,19 @@ Bash functions are reusable pieces of code that perform a specific task. They he
|
||||
|
||||
The basic syntax for defining a function in Bash is:
|
||||
|
||||
```bash
|
||||
```
|
||||
function_name() {
|
||||
# Function body
|
||||
# Commands go here
|
||||
# Function body
|
||||
# Commands go here
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can use the `function` keyword:
|
||||
|
||||
```bash
|
||||
```
|
||||
function function_name {
|
||||
# Function body
|
||||
# Commands go here
|
||||
# Function body
|
||||
# Commands go here
|
||||
}
|
||||
```
|
||||
|
||||
@ -28,7 +28,7 @@ function function_name {
|
||||
|
||||
To call a function, simply use its name:
|
||||
|
||||
```bash
|
||||
```
|
||||
function_name
|
||||
```
|
||||
|
||||
@ -43,9 +43,9 @@ Bash functions can accept parameters, which are accessed using special variables
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
greet() {
|
||||
echo "Hello, $1! Nice to meet you."
|
||||
echo "Hello, $1! Nice to meet you."
|
||||
}
|
||||
|
||||
greet "Alice" # Output: Hello, Alice! Nice to meet you.
|
||||
@ -55,13 +55,13 @@ greet "Alice" # Output: Hello, Alice! Nice to meet you.
|
||||
|
||||
Bash functions don't return values in the traditional sense. Instead, they use exit status:
|
||||
|
||||
```bash
|
||||
```
|
||||
is_even() {
|
||||
if (( $1 % 2 == 0 )); then
|
||||
return 0 # Success (true)
|
||||
else
|
||||
return 1 # Failure (false)
|
||||
fi
|
||||
if (( $1 % 2 == 0 )); then
|
||||
return 0 # Success (true)
|
||||
else
|
||||
return 1 # Failure (false)
|
||||
fi
|
||||
}
|
||||
|
||||
is_even 4
|
||||
@ -75,9 +75,9 @@ echo $? # Output: 1 (failure)
|
||||
|
||||
To capture a function's output, use command substitution:
|
||||
|
||||
```bash
|
||||
```
|
||||
get_date() {
|
||||
echo $(date +"%Y-%m-%d")
|
||||
echo $(date +"%Y-%m-%d")
|
||||
}
|
||||
|
||||
today=$(get_date)
|
||||
@ -88,10 +88,10 @@ echo "Today is $today"
|
||||
|
||||
Use the `local` keyword to declare variables that are only accessible within the function:
|
||||
|
||||
```bash
|
||||
```
|
||||
my_function() {
|
||||
local my_var="Hello, local variable!"
|
||||
echo $my_var
|
||||
local my_var="Hello, local variable!"
|
||||
echo $my_var
|
||||
}
|
||||
|
||||
my_function # Output: Hello, local variable!
|
||||
@ -102,13 +102,13 @@ echo $my_var # Output: (empty, as my_var is not accessible here)
|
||||
|
||||
Functions in Bash have access to global variables, but it's generally better to pass values as parameters:
|
||||
|
||||
```bash
|
||||
```
|
||||
global_var="I'm global"
|
||||
|
||||
my_function() {
|
||||
echo "Inside function: $global_var"
|
||||
local local_var="I'm local"
|
||||
echo "Local variable: $local_var"
|
||||
echo "Inside function: $global_var"
|
||||
local local_var="I'm local"
|
||||
echo "Local variable: $local_var"
|
||||
}
|
||||
|
||||
my_function
|
||||
@ -120,14 +120,14 @@ echo "Trying to access local_var: $local_var" # This will be empty
|
||||
|
||||
You can create function libraries by putting related functions in a separate file and sourcing it:
|
||||
|
||||
```bash
|
||||
```
|
||||
# In file: my_functions.sh
|
||||
greet() {
|
||||
echo "Hello, $1!"
|
||||
echo "Hello, $1!"
|
||||
}
|
||||
|
||||
farewell() {
|
||||
echo "Goodbye, $1!"
|
||||
echo "Goodbye, $1!"
|
||||
}
|
||||
|
||||
# In your main script
|
||||
@ -140,10 +140,10 @@ farewell "Bob"
|
||||
## 10. Advanced Techniques
|
||||
|
||||
a. Default Parameters:
|
||||
```bash
|
||||
```
|
||||
greet() {
|
||||
local name=${1:-"Guest"}
|
||||
echo "Hello, $name!"
|
||||
local name=${1:-"Guest"}
|
||||
echo "Hello, $name!"
|
||||
}
|
||||
|
||||
greet # Output: Hello, Guest!
|
||||
@ -151,27 +151,27 @@ greet "Alice" # Output: Hello, Alice!
|
||||
```
|
||||
|
||||
b. Variable Number of Arguments:
|
||||
```bash
|
||||
```
|
||||
sum() {
|
||||
local result=0
|
||||
for num in "$@"; do
|
||||
((result += num))
|
||||
done
|
||||
echo $result
|
||||
local result=0
|
||||
for num in "$@"; do
|
||||
((result += num))
|
||||
done
|
||||
echo $result
|
||||
}
|
||||
|
||||
sum 1 2 3 4 5 # Output: 15
|
||||
```
|
||||
|
||||
c. Recursive Functions:
|
||||
```bash
|
||||
```
|
||||
factorial() {
|
||||
if (( $1 <= 1 )); then
|
||||
echo 1
|
||||
else
|
||||
local prev=$(factorial $(($1 - 1)))
|
||||
echo $(($1 * prev))
|
||||
fi
|
||||
if (( $1 <= 1 )); then
|
||||
echo 1
|
||||
else
|
||||
local prev=$(factorial $(($1 - 1)))
|
||||
echo $(($1 * prev))
|
||||
fi
|
||||
}
|
||||
|
||||
factorial 5 # Output: 120
|
||||
@ -190,17 +190,13 @@ factorial 5 # Output: 120
|
||||
|
||||
Use the `set -x` command to enable debugging mode, which prints each command before executing it:
|
||||
|
||||
```bash
|
||||
```
|
||||
set -x # Enable debugging
|
||||
my_function() {
|
||||
echo "Doing something"
|
||||
local result=$((2 + 2))
|
||||
echo "Result: $result"
|
||||
echo "Doing something"
|
||||
local result=$((2 + 2))
|
||||
echo "Result: $result"
|
||||
}
|
||||
my_function
|
||||
set +x # Disable debugging
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Bash functions are powerful tools for creating modular, reusable code. They can significantly improve the organization and maintainability of your shell scripts. By mastering functions, you'll be able to write more efficient and elegant Bash scripts.
|
||||
|
||||
@ -6,13 +6,13 @@ The first step in debugging a bash script is to enable debugging mode. You can d
|
||||
|
||||
- Add the -x option when running the script:
|
||||
|
||||
```bash
|
||||
```
|
||||
bash -x your_script.sh
|
||||
```
|
||||
|
||||
- Add the set -x command at the beginning of your script:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
@ -25,13 +25,13 @@ The -x option enables trace debugging, which prints each command and its argumen
|
||||
|
||||
Bash provides several set options that can help with debugging:
|
||||
|
||||
- set -e: Exit immediately if a command exits with a non-zero status.
|
||||
- set -u: Treat unset variables as an error when substituting.
|
||||
- set -o pipefail: The return value of a pipeline is the status of the last command to exit with a non-zero status.
|
||||
- `set -e`: Exit immediately if a command exits with a non-zero status.
|
||||
- `set -u`: Treat unset variables as an error when substituting.
|
||||
- `set -o` pipefail: The return value of a pipeline is the status of the last command to exit with a non-zero status.
|
||||
|
||||
You can combine these options:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
set -x
|
||||
@ -43,7 +43,7 @@ set -x
|
||||
|
||||
Insert echo statements throughout your script to print variable values or to indicate which part of the script is being executed:
|
||||
|
||||
```bash
|
||||
```
|
||||
echo "Debug: Variable value is $variable"
|
||||
echo "Debug: Entering function foo"
|
||||
```
|
||||
@ -52,12 +52,12 @@ echo "Debug: Entering function foo"
|
||||
|
||||
Bash provides several built-in commands for debugging:
|
||||
|
||||
- set -v: Prints shell input lines as they are read.
|
||||
- `set -v`: Prints shell input lines as they are read.
|
||||
- trap: Can be used to debug functions or specific parts of your script.
|
||||
|
||||
Example of using trap:
|
||||
|
||||
```bash
|
||||
```
|
||||
trap 'echo "Line $LINENO: Command \\"$BASH_COMMAND\\" exited with status $?"' ERR
|
||||
```
|
||||
|
||||
@ -67,15 +67,11 @@ For more complex scripts, you might want to use a debugger. Bashdb is a popular
|
||||
|
||||
a) Install bashdb (on Ubuntu/Debian):
|
||||
|
||||
```
|
||||
sudo apt-get install bashdb
|
||||
```
|
||||
`sudo apt-get install bashdb`
|
||||
|
||||
b) Run your script with bashdb:
|
||||
|
||||
```
|
||||
bashdb your_script.sh
|
||||
```
|
||||
`bashdb your_script.sh`
|
||||
|
||||
This will start an interactive debugging session where you can set breakpoints, step through the code, and inspect variables.
|
||||
|
||||
@ -83,9 +79,7 @@ This will start an interactive debugging session where you can set breakpoints,
|
||||
|
||||
Before diving into debugging, check for syntax errors:
|
||||
|
||||
```bash
|
||||
bash -n your_script.sh
|
||||
```
|
||||
`bash -n your_script.sh`
|
||||
|
||||
This will check for syntax errors without executing the script.
|
||||
|
||||
@ -95,21 +89,17 @@ Shellcheck is a static analysis tool for shell scripts. It can catch common erro
|
||||
|
||||
a) Install shellcheck (on Ubuntu/Debian):
|
||||
|
||||
```
|
||||
sudo apt-get install shellcheck
|
||||
```
|
||||
`sudo apt-get install shellcheck`
|
||||
|
||||
b) Run shellcheck on your script:
|
||||
|
||||
```
|
||||
shellcheck your_script.sh
|
||||
```
|
||||
`shellcheck your_script.sh`
|
||||
|
||||
## 8. Debug specific sections
|
||||
|
||||
If you only want to debug a specific section of your script, you can use set -x and set +x to turn debugging on and off:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
# Normal execution
|
||||
@ -128,7 +118,7 @@ echo "Back to normal execution"
|
||||
|
||||
You can customize the prefix used for debug output using the PS4 variable:
|
||||
|
||||
```bash
|
||||
```
|
||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||
set -x
|
||||
|
||||
@ -141,11 +131,11 @@ This will prefix each debug line with the source file, line number, and function
|
||||
|
||||
After each important command, check its exit status:
|
||||
|
||||
```bash
|
||||
```
|
||||
important_command
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: important_command failed"
|
||||
exit 1
|
||||
echo "Error: important_command failed"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
@ -153,9 +143,7 @@ fi
|
||||
|
||||
You can use the DEBUG trap to execute a command before each command in your script:
|
||||
|
||||
```bash
|
||||
trap 'echo "About to execute: $BASH_COMMAND"' DEBUG
|
||||
```
|
||||
`trap 'echo "About to execute: $BASH_COMMAND"' DEBUG`
|
||||
|
||||
This will print each command before it's executed.
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ Bash scripts can accept arguments when executed from the command line. These arg
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
echo "The script name is: $0"
|
||||
@ -16,22 +16,20 @@ echo "All arguments: $@"
|
||||
```
|
||||
|
||||
Usage:
|
||||
```
|
||||
./script.sh arg1 arg2 arg3
|
||||
```
|
||||
`./script.sh arg1 arg2 arg3`
|
||||
|
||||
## 2. The `read` Command
|
||||
|
||||
The `read` command allows interactive user input during script execution.
|
||||
|
||||
Basic syntax:
|
||||
```bash
|
||||
```
|
||||
read variable_name
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
echo "What's your name?"
|
||||
@ -64,7 +62,7 @@ Bash provides special variables for working with command-line arguments:
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
echo "Number of arguments: $#"
|
||||
@ -83,44 +81,42 @@ You can create scripts that accept options (flags) to modify behavior.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
verbose=false
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
case $key in
|
||||
-v|--verbose)
|
||||
verbose=true
|
||||
shift
|
||||
;;
|
||||
-n|--name)
|
||||
name="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
key="$1"
|
||||
case $key in
|
||||
-v|--verbose)
|
||||
verbose=true
|
||||
shift
|
||||
;;
|
||||
-n|--name)
|
||||
name="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$verbose" = true ] ; then
|
||||
echo "Verbose mode on"
|
||||
echo "Verbose mode on"
|
||||
fi
|
||||
|
||||
if [ ! -z "$name" ] ; then
|
||||
echo "Hello, $name!"
|
||||
echo "Hello, $name!"
|
||||
fi
|
||||
```
|
||||
|
||||
Usage:
|
||||
```
|
||||
./script.sh -v --name John
|
||||
```
|
||||
`./script.sh -v --name John`
|
||||
|
||||
## 5. Validating Input
|
||||
|
||||
@ -128,19 +124,19 @@ It's important to validate user input to ensure your script behaves correctly.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
read -p "Enter a number between 1 and 10: " number
|
||||
|
||||
if [[ ! $number =~ ^[0-9]+$ ]] ; then
|
||||
echo "Error: Not a number"
|
||||
exit 1
|
||||
echo "Error: Not a number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( number < 1 || number > 10 )) ; then
|
||||
echo "Error: Number out of range"
|
||||
exit 1
|
||||
echo "Error: Number out of range"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "You entered a valid number: $number"
|
||||
@ -152,54 +148,52 @@ For more complex option parsing, Bash provides the `getopts` built-in command.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [-h] [-v] [-n name]"
|
||||
echo " -h: Display this help message"
|
||||
echo " -v: Enable verbose mode"
|
||||
echo " -n name: Specify a name"
|
||||
echo "Usage: $0 [-h] [-v] [-n name]"
|
||||
echo " -h: Display this help message"
|
||||
echo " -v: Enable verbose mode"
|
||||
echo " -n name: Specify a name"
|
||||
}
|
||||
|
||||
verbose=false
|
||||
name=""
|
||||
|
||||
while getopts ":hvn:" opt; do
|
||||
case ${opt} in
|
||||
h )
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
v )
|
||||
verbose=true
|
||||
;;
|
||||
n )
|
||||
name=$OPTARG
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
case ${opt} in
|
||||
h )
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
v )
|
||||
verbose=true
|
||||
;;
|
||||
n )
|
||||
name=$OPTARG
|
||||
;;
|
||||
\? )
|
||||
echo "Invalid option: $OPTARG" 1>&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
: )
|
||||
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$verbose" = true ] ; then
|
||||
echo "Verbose mode enabled"
|
||||
echo "Verbose mode enabled"
|
||||
fi
|
||||
|
||||
if [ ! -z "$name" ] ; then
|
||||
echo "Hello, $name!"
|
||||
echo "Hello, $name!"
|
||||
fi
|
||||
```
|
||||
|
||||
Usage:
|
||||
```
|
||||
./script.sh -v -n Alice
|
||||
```
|
||||
`./script.sh -v -n Alice`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user