Building Scalable Shell Script Utilities for Process Monitoring
Modularizing Shell Scripts for Process Management
Function Decomposition
The script architecture separates core functionalities into distinct functions:
fetch_groups- retrieves all group identifiers from configurationfetch_processes- lists process names like 'nginx httpd mysql datanode'retrieve_process_details- provides comprehensive process data including status, PID, CPU, memory, and start time; accepts an optional process name parameterlist_group_processes- returns all processes within a specified group
Configuration File Structure
The configuration file process.cfg defines service groups and their associated processes:
[GROUP_LIST]
WEB
DB
HADOOP
YARN
[WEB]
nginx
httpd
[DB]
mysql
postgresql
oracle
[HADOOP]
datanode
namenode
journalnode
[YARN]
resourcemanager
nodemanager
Implementation Details
Retrieving Group Identifiers
fetch_groups() {
sed -n '/\[GROUP_LIST\]/,/{.*}/p' "$CONFIG_PATH" | egrep -v '(^$|\[.*\])'
}
Fetching Processes With in Groups
fetch_processes() {
for group in $(fetch_groups); do
sed -n "/\[$group\]/,/{.*}/p" "$CONFIG_PATH" | egrep -v '(^$|\[.*\])'
done
}
Process ID Retrieval
get_pid_by_name() {
if [ $# -ne 1 ]; then
return 1
else
ps -ef | grep "$1" | grep -v grep | grep -v "$0" | awk '{print $2}'
fi
}
Detailed Process Information
get_process_info() {
local pid="$1"
if [ "$(ps -ef | awk -v target_pid="$pid" '$2==target_pid{print}' | wc -l)" -eq 1 ]; then
status="RUNNING"
else
status="STOPPED"
fi
cpu_usage=$(ps aux | awk -v target_pid="$pid" '$2==target_pid{print $3}')
mem_usage=$(ps aux | awk -v target_pid="$pid" '$2==target_pid{print $4}')
start_time=$(ps -p "$pid" -o lstart | grep -v STARTED)
}
Group Vaildation and Process Listing
validate_group() {
for group in $(fetch_groups); do
if [ "$group" = "$1" ]; then
return 0
fi
done
return 1
}
list_group_processes() {
if validate_group "$1"; then
sed -n "/\[$1\]/,/{.*}/p" "$CONFIG_PATH" | egrep -v '(^$|^#|\[.*\])'
else
echo "Group $1 not found in configuration"
fi
}
Main Execution Logic
The script supports three operational modes:
- No arguments: displays status of all configured processes
-g GROUP_NAME: shows all processes in the specified groupPROCESS_NAME: displays detailed status of the specified process
main() {
# Print header
printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n" "ProcessName---" "GroupName---" "Status---" "Pid---" "CPU---" "MEMORY---" "StartTime---"
if [ $# -eq 0 ]; then
# Show all processes
for proc in $(fetch_processes); do
group=$(get_group_for_process "$proc")
is_valid_process "$proc" && format_output "$proc" "$group"
done
elif [ "$1" = "-g" ]; then
# Show specific groups
shift
for group in "$@"; do
is_valid_group "$group" || continue
for proc in $(list_group_processes "$group"); do
is_valid_process "$proc" && format_output "$proc" "$group"
done
done
else
# Show specific processes
for proc in "$@"; do
group=$(get_group_for_process "$proc")
is_valid_process "$proc" && format_output "$proc" "$group"
done
fi
}
Output Formatting
format_output() {
local process="$1"
local group="$2"
if ps -ef | grep "$process" | grep -v grep | grep -v "$0" > /dev/null; then
local pids=$(get_pid_by_name "$process")
for pid in $pids; do
get_process_info "$pid"
printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n" "$process" "$group" "$status" "$pid" "$cpu_usage" "$mem_usage" "$start_time"
done
else
printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n" "$process" "$group" "NULL" "Stopped" "NULL" "NULL" "NULL"
fi
}
The implemantation handles process validation, group membership checks, and structured output formatting for comprehensive system monitoring.