Shell Scripting Guide : How to Show Performance Stats
After you read my post about Shell Scripting Guide : Basic Shell Scripting, in this step you will practice a simple project which is can boost your basic shell scripting. Lets make it!
Prerequisites:
- Reference project : https://roadmap.sh/projects/server-stats
- Acces machine with ssh, this article used ubuntu as an example
- Login as root
Make file server-stats.sh
File server-stats.sh has created, you can check with command ls
Add Executable Access to This File
Because by default, that file not assign to executable, we can add this access with command:
Open with nano
if you need install nano, you can type $ sudo apt-get update -y && apt-get install nano -y
You will see blank space but don't worry, we will make the syntax together step-by-step.
Let's Create Line-by-line this Code
In first line, we used a shell script to specify the interpreter that should be used to execute the script which is bash shell with location at /bin/bash
#!/bin/bash
Now, we reset the colour of output shell
# Reset
Color_Off='\033[0m' # Text Reset
# Regular Colors
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
DarkGray='\033[1;30m' # DarkGray
Next, we create a function to run percentage of cpu usage. The code is:
cpu_utilization() {
total_percentage=$(ps -e -o pcpu --no-headers | awk '{s+=$1} END {print s}');
cpu_count=$(grep -c ^processor /proc/cpuinfo)
percentage=$(awk "BEGIN {printf \"%.2f\", $total_percentage / $cpu_count}")
printf " ${Cyan}CPU${Color_Off}"
echo_progress_bar "$percentage"
printf "\n"
}
Next, we create a function to run percentage of RAM usage. The code is:
mem_utilization() {
percentage=$(ps -e -o pmem --no-headers | awk '{s+=$1} END {print s}')
available=$(awk '/MemAvailable/ {print $2"K"}' /proc/meminfo | numfmt --from=iec --to=iec-i)
total=$(awk '/MemTotal/ {print $2"K"}' /proc/meminfo | numfmt --from=iec --to=iec-i)
printf " ${Cyan}RAM${Color_Off}"
echo_progress_bar "$percentage"
printf " ${Cyan}Available $White$available ${Cyan}Total $White$total$Color_Off"
printf "\n"
}
Now, we create a function to show usage of strorage. The code is:
disk_usage() {
available=$(df -h / --output=avail | tail -n 1)
percentage=$(df -h / --output=pcent | tail -n 1 | sed 's/%//g')
used=$(df -h / --output=used | tail -n 1)
printf "${Cyan}DISK${Color_Off}"
echo_progress_bar "$percentage"
printf " ${Cyan}Available $White$available ${Cyan}Used $White$used$Color_Off"
printf "\n"
}
Next, we create top 5 of every server stats
top_5_process_cpu() {
ps -e -o pcpu,comm --sort=-pcpu | head -n 6 | tail -n 5
}
top_5_process_mem() {
ps -e -o pmem,comm --sort=-pmem | head -n 6 | tail -n 5
}
echo_top_5_process_cpu() {
printf "${Cyan}%-36s${Color_Off}\n" "Top 5 CPU Processes$Color_Off"
awk '{ printf "%-7s %-29s\n", " "$1"%", $2 }' <(top_5_process_cpu)
}
echo_top_5_process_mem() {
printf "${Cyan}%-36s${Color_Off}\n" "Top 5 RAM Processes$Color_Off"
awk '{ printf "%-7s %-29s\n", " "$1"%", $2 }' <(top_5_process_mem)
}
echo_top_5_process_side_by_side() {
printf "${Cyan}%-36s %-36s${Color_Off}\n" "Top 5 CPU Processes" "Top 5 RAM Processes"
paste <(top_5_process_cpu) <(top_5_process_mem) | awk '{ printf "%-7s %-29s %-6s %-30s\n", " "$1"%", $2, $3"%", $4 }'
}
Now, lets make a function to show current user has login
echo_current_users() {
users=$(who | wc -l)
printf "${Cyan}Current Users ($White$users sessions$Cyan)${Color_Off}\n"
printf "$(who | cut -d " " -f 1 | sort | awk 'BEGIN { ORS=" " }; {print $1}')"
printf "\n"
}
After that, we create function to show failed login for every user login
echo_failed_login() {
printf "${Cyan}Failed Login Attempts${Color_Off}\n"
if [ ! -f /var/log/auth.log -o ! -r /var/log/auth.log ]; then
printf "$Red Log file /var/log/auth.log not found or not readable\n$Color_Off"
return
fi
awk '/Failed password/ {print $1}' /var/log/auth.log | sort | uniq -c | sort -nr | head -n 5
}
Next, we create function to show uptime and os in this system
echo_uptime() {
uptime_days=$(uptime | awk '{print $3" "$4" "$5}' | sed 's/,//g')
printf "${Cyan}Uptime${Color_Off} $uptime_days $uptime_hours\n"
}
echo_os() {
os=$(cat /etc/os-release | grep PRETTY_NAME | cut -d "=" -f 2 | sed 's/"//g')
printf "${Cyan}OS${Color_Off} $os\n"
}
To show progress bar of usage of CPU, RAM, and Strorage, we create a function below:
echo_progress_bar() {
percentage=$(printf '%.0f\n' $1)
bar_count=$((percentage / 2))
if [ $bar_count -lt 35 ]; then
color=$Green
elif [ $bar_count -lt 45 ]; then
color=$Yellow
else
color=$Red
fi
printf "$White[$color"
printf '%*s' "$bar_count" '' | tr ' ' '|'
printf '%*s' $((50 - bar_count)) ' '
printf "$DarkGray$percentage%%$White]$Color_Off"
}
Now, we create a function to interact with user
usage() {
echo "Usage: $0 [options]"
echo "Options:"
echo " -c, --cpu Show CPU utilization"
echo " -m, --mem Show memory utilization"
echo " -d, --disk Show disk usage"
echo " -t, --top Show top 5 processes by CPU and memory usage side by side"
echo " --top_ram Show top 5 processes by memory usage"
echo " --top_cpu Show top 5 processes by CPU usage"
echo " -u, --users Show current users"
echo " -f, --failed Show failed login attempts"
echo " --uptime Show uptime"
echo " --os Show OS"
echo " -h, --help Show this help message"
}
We create condition script performs certain actions only if no arguments are provided when running the script. These actions involve displaying information about CPU, memory, disk, processes, current users, and failed login attempts.
if [ $# -eq 0 ]; then
cpu_utilization
mem_utilization
disk_usage
printf "\n"
echo_top_5_process_side_by_side
echo_current_users
echo_failed_login
fi
Next, we create conditional script uses a while loop to process command-line arguments provided by the user. For each argument, it uses a case statement to determine the appropriate action, such as calling functions to display system information like CPU, memory, disk usage, and more.
while [ $# -gt 0 ]; do
case $1 in
-c|--cpu)
cpu_utilization
;;
-m|--mem)
mem_utilization
;;
-d|--disk)
disk_usage
;;
-t|--top)
echo_top_5_process_side_by_side
;;
--top_ram)
echo_top_5_process_mem
;;
--top_cpu)
echo_top_5_process_cpu
;;
-u|--users)
echo_current_users
;;
-f|--failed)
echo_failed_login
;;
--uptime)
echo_uptime
;;
--os)
echo_os
;;
-h|--help)
usage
exit 0
;;
*)
echo "Invalid argument: $1 use -h or --help for usage"
exit 1
;;
esac
shift
done
Last, don't forget we return exit code 0
to show the script has run well
exit 0
Congratulations! We have successfully practice some basic of shell scripting. If you need full of script, you can going to this link:
https://gist.github.com/ridhodevnurhuda/94f0330b510c08ff1247175f06752def
Let’s explore more advanced shell scripting, see you the next post!