Bash Scripting
Bash scripting is used to automate Linux command-line tasks. A script can take user input, store values in variables, make decisions, repeat actions with loops, and save output for later analysis.
For cybersecurity work, Bash is useful for tasks such as host discovery, log parsing, file checks, simple reconnaissance, backups, and tool automation.
Script Structure
A Bash script usually begins with a shebang, which tells Linux what interpreter should run the file.
Common interpreter examples:
| Shebang | Meaning |
|---|---|
#!/bin/bash |
Run the script with Bash |
#!/usr/bin/env python3 |
Run the script with Python 3 |
After creating a script, make it executable:
Then run it:
Arguments and Special Variables
Arguments are values passed to a script from the command line.
In this example, example.com becomes $1.
| Variable | Meaning |
|---|---|
$0 |
Script name |
$1, $2, $3 |
Positional arguments |
${10} |
Tenth argument and above |
$# |
Number of arguments |
$@ |
All arguments |
$? |
Exit status of the last command |
$$ |
Process ID of the current script |
Example:
Variables
Variables store values for reuse.
Assignment uses no spaces around =.
Incorrect:
Bash will treat target as a command and fail.
Arrays
Arrays store multiple values in one variable.
Array indexes start at 0.
If an array item contains spaces, quote it:
Conditional Logic
Conditional logic lets a script make decisions.
Basic structure:
Example: validating that the user provided one argument.
#!/bin/bash
if [ $# -eq 0 ]
then
echo "Error: You must specify a target domain."
echo "Usage: $0 <domain>"
exit 1
elif [ $# -eq 1 ]
then
domain=$1
echo "Processing domain: $domain"
else
echo "Error: Too many arguments."
exit 1
fi
Comparison Operators
Bash uses different operators depending on whether you are comparing strings, numbers, or files.
Integer Operators
| Operator | Meaning | Example |
|---|---|---|
-eq |
Equal to | [ "$count" -eq 1 ] |
-ne |
Not equal to | [ "$count" -ne 0 ] |
-lt |
Less than | [ "$count" -lt 5 ] |
-gt |
Greater than | [ "$count" -gt 5 ] |
-ge |
Greater than or equal to | [ "$count" -ge 10 ] |
File Operators
| Operator | Meaning |
|---|---|
-e |
Path exists |
-f |
Is a regular file |
-d |
Is a directory |
-r |
Is readable |
-w |
Is writable |
-x |
Is executable |
-s |
File exists and is not empty |
Example:
#!/bin/bash
if [[ -e "$1" && -r "$1" ]]
then
echo "Access granted: Reading $1..."
cat "$1"
elif [[ -e "$1" && ! -r "$1" ]]
then
echo "Permission error: You do not have read rights for $1."
exit 1
else
echo "Error: File not found."
exit 2
fi
Logical Operators
Use double brackets [[ ... ]] when combining conditions.
| Operator | Meaning |
|---|---|
&& |
Logical AND |
|| |
Logical OR |
! |
Logical NOT |
Example:
Arithmetic Operations
Bash supports integer arithmetic by default.
| Operator | Meaning |
|---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Division |
% |
Modulus |
++ |
Increment |
-- |
Decrement |
Use arithmetic expansion when you want to print or use the result:
Use arithmetic evaluation when updating a variable:
Bash does not handle decimal math by default. Use tools such as bc for floating-point calculations.
String Length
Use ${#variable} to count the number of characters in a variable.
Functions
Functions make scripts easier to organize and reuse.
A function must be defined before it is called.
Alternative syntax:
Inside a function, $1, $2, and other positional parameters refer to the function arguments, not the script arguments.
Variable Scope in Functions
By default, Bash variables are global.
Use local to limit a variable to a function.
This helps prevent accidental overwrites in larger scripts.
Function Return Values
Bash functions return exit status codes, not normal data values.
| Return Code | Meaning |
|---|---|
0 |
Success |
| Non-zero | Error or failure |
Example:
To return actual text or data, print it with echo and capture it with command substitution:
Input with read
The read command lets a script accept user input.
The -p option displays a prompt before waiting for input.
Case Statements
A case statement is useful for menus and handling multiple fixed options.
read -p "Select your option: " opt
case $opt in
"1")
echo "Running scan..."
;;
"2")
echo "Running exploit..."
;;
*)
echo "Invalid option."
exit 1
;;
esac
Important syntax:
| Syntax | Meaning |
|---|---|
case $var in |
Starts the case block |
pattern) |
Matches a value |
;; |
Ends a branch |
*) |
Default catch-all branch |
esac |
Ends the case block |
Loops
Loops repeat a block of code.
For Loops
Use a for loop when you already have a known list.
One-line version:
While Loops
A while loop runs while a condition is true.
Until Loops
An until loop runs while a condition is false.
Loop Control
| Command | Meaning |
|---|---|
break |
Exit the loop immediately |
continue |
Skip the current iteration and move to the next one |
Output Control with tee
Redirection saves output to a file but hides it from the terminal.
The tee command displays output on the screen and saves it to a file at the same time.
Append instead of overwrite:
Comparison:
| Method | Syntax | Visible in Terminal | Saved to File |
|---|---|---|---|
| Standard output | command |
Yes | No |
| Redirection | command > file |
No | Yes |
| Tee | command \| tee file |
Yes | Yes |
Example:
This prints discovered hosts to the terminal and saves them to discovered_hosts.txt.
Practical Script Example
This example combines arguments, validation, functions, loops, and output logging.
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Usage: $0 <domain>"
exit 1
fi
domain=$1
output_file="discovered_hosts.txt"
find_hosts() {
host "$domain" | grep "has address" | cut -d " " -f4 | tee "$output_file"
}
ping_hosts() {
while read -r ip
do
if ping -c 1 "$ip" > /dev/null 2>&1
then
echo "$ip is up"
else
echo "$ip is down"
fi
done < "$output_file"
}
find_hosts
ping_hosts
Quick Reference
| Concept | Syntax / Command |
|---|---|
| Shebang | #!/bin/bash |
| First argument | $1 |
| Argument count | $# |
| All arguments | $@ |
| Last exit status | $? |
| Variable assignment | name="value" |
| Array | items=(one two three) |
| If statement | if [ condition ]; then ... fi |
| Case statement | case $var in ... esac |
| For loop | for item in list; do ... done |
| While loop | while [ condition ]; do ... done |
| Function | name() { commands; } |
| Arithmetic | $((x + y)) |
| Save and display output | command \| tee file.txt |