mirror of
https://github.com/bvanroll/_dotfiles.git
synced 2025-08-29 20:12:42 +00:00
101 lines
3.8 KiB
Bash
Executable File
101 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# cpu_util_detailed
|
|
# Meant for usage as an i3blocks blocklet.
|
|
# It reports detailed CPU utilization in colors using pango markup.
|
|
# Written by skidnik <skidnik@gmail.com>
|
|
# Licensed under GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
|
|
#
|
|
# Defaults if not set
|
|
interval=${interval:-0} # just in case it's started not by i3blocks
|
|
stats=${stats:-usr nice sys iowait}
|
|
format=${format:-%6.2f}
|
|
warn=${warn:-80}
|
|
declare -A colormap=(
|
|
[usr]=${usr_color:-green}
|
|
[nice]=${nice_color:-yellow}
|
|
[sys]=${sys_color:-red}
|
|
[iowait]=${iowait_color:-grey}
|
|
[irq]=${irq_color:-purple}
|
|
[soft]=${soft_color:-violet}
|
|
[steal]=${steal_color:-orange}
|
|
[guest]=${guest_color:-cyan}
|
|
[gnice]=${gnice_color:-blue}
|
|
[idle]=${idle_color:-white}
|
|
[total]=${total_color:-white}
|
|
)
|
|
# If $report_time not set:
|
|
# Set it to $interval - 1, but not less than 1.
|
|
# If $interval is 'repeat' or -2 set report_time to 5.
|
|
if [[ -z $report_time ]]; then
|
|
if [[ "$interval" =~ ^-?[0-9]+$ ]];
|
|
then
|
|
if [[ $interval -gt 2 ]]; then
|
|
report_time=$(( interval - 1 ))
|
|
elif [[ $interval == -2 ]]; then
|
|
report_time=5
|
|
else
|
|
report_time=1
|
|
fi
|
|
elif [[ $interval == repeat ]]; then
|
|
report_time=5
|
|
fi
|
|
fi
|
|
# 'idle' is hardcoded as it's always required, no need to ask for it two times.
|
|
getstats=${stats//idle /}
|
|
# Get detailed CPU load as a set of variables with same names:
|
|
if _mpstat="$(command -v mpstat)"
|
|
then
|
|
declare $( ${_mpstat} -u "$report_time" 1 | sed -n '3,4p' | awk -v stats="$getstats idle" '
|
|
BEGIN{
|
|
split(stats, fields)
|
|
}
|
|
{
|
|
split($0, headers)
|
|
getline
|
|
split($0, values)
|
|
for (i in fields) {
|
|
for (j in headers)
|
|
if ( headers[j] ~ "^%" fields[i] ) {
|
|
printf "%s=%s\n", fields[i], values[j]
|
|
}
|
|
}
|
|
}
|
|
')
|
|
total=$( bc <<<"scale=2; 100 - $idle" )
|
|
else
|
|
# This is a fallback way for the case `mpstat` is not available
|
|
start_uptime=($(cat /proc/uptime))
|
|
start=($(sed -n '1p' /proc/stat))
|
|
sleep ${report_time}
|
|
end_uptime=($(cat /proc/uptime))
|
|
end=($(sed -n '1p' /proc/stat))
|
|
user_hz=$(getconf CLK_TCK)
|
|
num_cpus=$(nproc --all)
|
|
delta_time=$( bc <<<"scale=2; ${end_uptime[0]}-${start_uptime[0]}" )
|
|
user_hz_time=$( bc <<<"$delta_time * $user_hz" )
|
|
usr=$( bc <<<"scale=4; (${end[1]}-${start[1]})/$num_cpus/$user_hz_time*100" )
|
|
nice=$( bc <<<"scale=4; (${end[2]}-${start[2]})/$num_cpus/$user_hz_time*100" )
|
|
sys=$( bc <<<"scale=4; (${end[3]}-${start[3]})/$num_cpus/$user_hz_time*100" )
|
|
idle=$( bc <<<"scale=4; (${end[4]}-${start[4]})/$num_cpus/$user_hz_time*100" )
|
|
iowait=$( bc <<<"scale=4; (${end[5]}-${start[5]})/$num_cpus/$user_hz_time*100" )
|
|
irq=$( bc <<<"scale=4; (${end[6]}-${start[6]})/$num_cpus/$user_hz_time*100" )
|
|
soft=$( bc <<<"scale=4; (${end[7]}-${start[7]})/$num_cpus/$user_hz_time*100" )
|
|
steal=$( bc <<<"scale=4; (${end[8]}-${start[8]})/$num_cpus/$user_hz_time*100" )
|
|
guest=$( bc <<<"scale=4; (${end[9]}-${start[9]})/$num_cpus/$user_hz_time*100" )
|
|
gnice=$( bc <<<"scale=4; (${end[10]}-${start[10]})/$num_cpus/$user_hz_time*100" )
|
|
total=$( bc <<<"scale=4; ${end_uptime[1]}-${start_uptime[1]}" )
|
|
fi
|
|
# Output stats with pango formatting in a defined order
|
|
for stat in $stats
|
|
do
|
|
# No other way to make format adjustable
|
|
# shellcheck disable=SC2059
|
|
printf "<span color='%s'>$format</span>" "${colormap[$stat]}" "${!stat}"
|
|
done
|
|
echo # trailing newline
|
|
# Short text
|
|
# shellcheck disable=SC2059
|
|
printf "$format\n" "$total"
|
|
# Set urgent flag if over warn threshold
|
|
(( $( bc <<<"$total >= $warn" ) )) && exit 33 || :
|