Last active
March 30, 2026 21:04
-
-
Save denisfl/3001a0045f6f132b07125cd543f43168 to your computer and use it in GitHub Desktop.
Simple monitoring script for RPI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # ╔══════════════════════════════════════════════╗ | |
| # ║ Tokyo Night Bento Monitor ║ | |
| # ║ macOS · Linux · Raspberry Pi ║ | |
| # ╚══════════════════════════════════════════════╝ | |
| # ── Tokyo Night palette ────────────────────────────────────── | |
| RESET=$'\e[0m'; BOLD=$'\e[1m' | |
| C_BDR=$'\e[38;2;86;95;137m' | |
| C_TTL=$'\e[38;2;122;162;247m' | |
| C_TXT=$'\e[38;2;192;202;245m' | |
| C_DIM=$'\e[38;2;86;95;137m' | |
| C_GRN=$'\e[38;2;158;206;106m' | |
| C_YLW=$'\e[38;2;224;175;104m' | |
| C_RED=$'\e[38;2;247;118;142m' | |
| C_CYN=$'\e[38;2;125;207;255m' | |
| C_PRP=$'\e[38;2;187;154;247m' | |
| C_ORG=$'\e[38;2;255;158;100m' | |
| C_TEL=$'\e[38;2;42;195;222m' | |
| # ── OS detection ───────────────────────────────────────────── | |
| OS="linux" | |
| [[ "$(uname)" == "Darwin" ]] && OS="macos" | |
| IS_RPI=0 | |
| [[ -f /proc/device-tree/model ]] && grep -qi "raspberry" /proc/device-tree/model 2>/dev/null && IS_RPI=1 | |
| # ── Card drawing helpers ───────────────────────────────────── | |
| hline() { printf '─%.0s' $(seq 1 "$1"); } | |
| ctop() { printf "${C_BDR}╭$(hline $1)╮${RESET}\n"; } | |
| cbot() { printf "${C_BDR}╰$(hline $1)╯${RESET}\n"; } | |
| csep() { printf "${C_BDR}├$(hline $1)┤${RESET}\n"; } | |
| cemp() { printf "${C_BDR}│%${1}s│${RESET}\n" ""; } | |
| ctitle() { | |
| local iw=$1 t=$2 tl=${#2} | |
| local l=$(( (iw - tl) / 2 )) r=$(( iw - tl - (iw - tl) / 2 )) | |
| printf "${C_BDR}│${RESET}%${l}s${BOLD}${C_TTL}%s${RESET}%${r}s${C_BDR}│${RESET}\n" "" "$t" "" | |
| } | |
| # cline <inner_w> <label> <value> [lc] [vc] | |
| cline() { | |
| local iw=$1 lbl=$2 val=$3 lc="${4:-$C_DIM}" vc="${5:-$C_TXT}" | |
| local gap=$(( iw - 2 - ${#lbl} - ${#val} )) | |
| [[ $gap -lt 1 ]] && gap=1 | |
| printf "${C_BDR}│${RESET} ${lc}%s${RESET}%${gap}s${vc}%s${RESET} ${C_BDR}│${RESET}\n" "$lbl" "" "$val" | |
| } | |
| # cbar <inner_w> <label> <bar_str> <bar_vis_w> <pct> | |
| cbar() { | |
| local iw=$1 lbl=$2 bstr=$3 bvw=$4 pct=$5 | |
| local pcts; printf -v pcts "%3d%%" "$pct" | |
| local gap=$(( iw - 2 - ${#lbl} - bvw - 1 - ${#pcts} )) | |
| [[ $gap -lt 1 ]] && gap=1 | |
| printf "${C_BDR}│${RESET} ${C_DIM}%s${RESET}%${gap}s%s ${C_TXT}%s${RESET} ${C_BDR}│${RESET}\n" \ | |
| "$lbl" "" "$bstr" "$pcts" | |
| } | |
| bar() { | |
| local pct=$1 w=${2:-20} | |
| local filled=$(( pct * w / 100 )) empty=$(( w - pct * w / 100 )) | |
| local col="$C_GRN" | |
| [[ $pct -ge 60 ]] && col="$C_YLW" | |
| [[ $pct -ge 85 ]] && col="$C_RED" | |
| local s="$col" | |
| for ((i=0;i<filled;i++)); do s+="█"; done | |
| s+="$C_DIM" | |
| for ((i=0;i<empty;i++)); do s+="░"; done | |
| printf "%s%s" "$s" "$RESET" | |
| } | |
| # sbs <iw_l> <iw_r> <left_arr_name> <right_arr_name> | |
| sbs() { | |
| local iwl=$1 iwr=$2 | |
| local -n _L=$3 _R=$4 | |
| local el er | |
| printf -v el "${C_BDR}│%${iwl}s│${RESET}" "" | |
| printf -v er "${C_BDR}│%${iwr}s│${RESET}" "" | |
| local max=${#_L[@]}; [[ ${#_R[@]} -gt $max ]] && max=${#_R[@]} | |
| for ((i=0;i<max;i++)); do | |
| printf "%s %s\n" "${_L[$i]:-$el}" "${_R[$i]:-$er}" | |
| done | |
| } | |
| # ── Data collectors ────────────────────────────────────────── | |
| collect_common() { | |
| HOSTNAME=$(hostname) | |
| NOW=$(date '+%Y-%m-%d %H:%M:%S') | |
| if [[ $OS == "macos" ]]; then | |
| UPTIME=$(uptime | sed 's/.*up //' | sed 's/,.*//' | xargs) | |
| else | |
| UPTIME=$(uptime -p 2>/dev/null | sed 's/up //' || uptime | sed 's/.*up //' | sed 's/,.*//' | xargs) | |
| fi | |
| } | |
| collect_cpu_macos() { | |
| CPU_CORES=$(sysctl -n hw.logicalcpu 2>/dev/null || echo "?") | |
| CPU_MODEL=$(sysctl -n machdep.cpu.brand_string 2>/dev/null \ | |
| | sed 's/Apple //' | sed 's/(R)//g' | sed 's/(TM)//g' \ | |
| | awk '{print substr($0,1,22)}') | |
| # CPU usage via top (2 samples) | |
| local idle | |
| idle=$(top -l 2 -n 0 -s 1 2>/dev/null | grep "CPU usage" | tail -1 \ | |
| | grep -oP '[0-9.]+(?=% idle)') | |
| [[ -n "$idle" ]] && CPU_PCT=$(awk "BEGIN{printf \"%d\",100-$idle}") || CPU_PCT=0 | |
| # CPU temp via powermetrics (needs sudo) or osx-cpu-temp if installed | |
| if command -v osx-cpu-temp &>/dev/null; then | |
| TEMP_RAW=$(osx-cpu-temp 2>/dev/null | grep -oP '[0-9.]+') | |
| TEMP_UNIT="°C" | |
| elif [[ -f /usr/bin/powermetrics ]]; then | |
| # Try without sudo — returns nothing if no perms, graceful fallback | |
| local pm | |
| pm=$(sudo -n powermetrics -n 1 --samplers smc 2>/dev/null | grep "CPU die" | grep -oP '[0-9.]+' | head -1) | |
| TEMP_RAW="${pm:-N/A}"; TEMP_UNIT="°C" | |
| else | |
| TEMP_RAW="N/A"; TEMP_UNIT="" | |
| fi | |
| ARM_FREQ="N/A"; GPU_FREQ="N/A"; THR_V="N/A"; THR_C="$C_DIM" | |
| } | |
| collect_cpu_linux() { | |
| CPU_CORES=$(nproc 2>/dev/null || echo "?") | |
| CPU_MODEL=$(grep -m1 "model name" /proc/cpuinfo 2>/dev/null \ | |
| | sed 's/.*: //' | sed 's/ */ /g' | awk '{print substr($0,1,22)}' \ | |
| || echo "N/A") | |
| local idle | |
| idle=$(top -bn2 -d0.3 | grep "Cpu(s)" | tail -1 \ | |
| | awk '{for(i=1;i<=NF;i++) if($i~/id,/){gsub(/[^0-9.]/,"",$i);print $i}}') | |
| [[ -n "$idle" ]] && CPU_PCT=$(awk "BEGIN{printf \"%d\",100-$idle}") || CPU_PCT=0 | |
| if [[ $IS_RPI -eq 1 ]] && command -v vcgencmd &>/dev/null; then | |
| TEMP_RAW=$(vcgencmd measure_temp 2>/dev/null | grep -oP '[0-9.]+') | |
| local ah gh | |
| ah=$(vcgencmd measure_clock arm 2>/dev/null | grep -oP '\d+') | |
| gh=$(vcgencmd measure_clock core 2>/dev/null | grep -oP '\d+') | |
| [[ "$ah" =~ ^[0-9]+$ ]] && ARM_FREQ="$(( ah/1000000 )) MHz" || ARM_FREQ="N/A" | |
| [[ "$gh" =~ ^[0-9]+$ ]] && GPU_FREQ="$(( gh/1000000 )) MHz" || GPU_FREQ="N/A" | |
| local traw; traw=$(vcgencmd get_throttled 2>/dev/null | grep -oP '0x[0-9a-fA-F]+') | |
| if [[ "$traw" == "0x0" ]]; then THR_V="none"; THR_C="$C_GRN" | |
| elif [[ -n "$traw" ]]; then THR_V="$traw"; THR_C="$C_RED" | |
| else THR_V="N/A"; THR_C="$C_DIM"; fi | |
| else | |
| TEMP_RAW=$(awk '{printf "%.1f",$1/1000}' /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo "N/A") | |
| ARM_FREQ="N/A"; GPU_FREQ="N/A"; THR_V="N/A"; THR_C="$C_DIM" | |
| fi | |
| TEMP_UNIT="°C" | |
| } | |
| collect_mem_macos() { | |
| # Physical RAM | |
| local total_b; total_b=$(sysctl -n hw.memsize 2>/dev/null) | |
| # vm_stat gives pages; pagesize from sysctl | |
| local pagesize; pagesize=$(sysctl -n hw.pagesize 2>/dev/null || echo 4096) | |
| local vm; vm=$(vm_stat 2>/dev/null) | |
| local free_p wired_p active_p inactive_p specul_p compress_p | |
| free_p=$( awk '/^Pages free:/ {gsub(/\./,"",$3);print $3}' <<< "$vm") | |
| wired_p=$( awk '/^Pages wired down:/ {gsub(/\./,"",$4);print $4}' <<< "$vm") | |
| active_p=$( awk '/^Pages active:/ {gsub(/\./,"",$3);print $3}' <<< "$vm") | |
| compress_p=$(awk '/^Pages occupied by compressor:/ {gsub(/\./,"",$5);print $5}' <<< "$vm") | |
| specul_p=$( awk '/^Pages speculative:/ {gsub(/\./,"",$3);print $3}' <<< "$vm") | |
| # "used" = wired + active + compressed (excludes inactive/speculative) | |
| local used_p=$(( (wired_p + active_p + compress_p) )) | |
| local free_p_adj=$(( free_p + specul_p )) | |
| local used_b=$(( used_p * pagesize )) | |
| local free_b=$(( free_p_adj * pagesize )) | |
| RAM_PCT=$(awk "BEGIN{printf \"%d\",($used_b/$total_b)*100}") | |
| RAM_TOT=$(awk "BEGIN{printf \"%.1f GiB\",$total_b/1073741824}") | |
| RAM_USE=$(awk "BEGIN{printf \"%.1f GiB\",$used_b/1073741824}") | |
| RAM_FRE=$(awk "BEGIN{printf \"%.1f GiB\",$free_b/1073741824}") | |
| # Swap | |
| local swapinfo; swapinfo=$(sysctl -n vm.swapusage 2>/dev/null) | |
| local stot suse | |
| stot=$(awk '{for(i=1;i<=NF;i++) if($i=="total") {gsub(/M/,"",$i+1);print $i+1}}' <<< "$swapinfo") | |
| suse=$(awk '{for(i=1;i<=NF;i++) if($i=="used") {gsub(/M/,"",$i+1);print $i+1}}' <<< "$swapinfo") | |
| if [[ -n "$stot" && "$stot" != "0.00" ]]; then | |
| SWP_PCT=$(awk "BEGIN{printf \"%d\",($suse/$stot)*100}" 2>/dev/null || echo 0) | |
| SWP_USE=$(awk "BEGIN{printf \"%.0f MiB\",$suse}" 2>/dev/null || echo "0 MiB") | |
| SWP_TOT=$(awk "BEGIN{printf \"%.0f MiB\",$stot}" 2>/dev/null || echo "0 MiB") | |
| HAS_SWAP=1 | |
| else | |
| SWP_PCT=0; SWP_USE="0"; SWP_TOT="0"; HAS_SWAP=0 | |
| fi | |
| } | |
| collect_mem_linux() { | |
| read -r RB_TOT RB_USE RB_FRE <<< "$(free -b | awk '/^Mem:/{print $2,$3,$4}')" | |
| RAM_PCT=$(awk "BEGIN{printf \"%d\",($RB_USE/$RB_TOT)*100}") | |
| RAM_TOT=$(awk "BEGIN{printf \"%.1f GiB\",$RB_TOT/1073741824}") | |
| RAM_USE=$(awk "BEGIN{printf \"%.1f GiB\",$RB_USE/1073741824}") | |
| RAM_FRE=$(awk "BEGIN{printf \"%.1f GiB\",$RB_FRE/1073741824}") | |
| read -r SB_TOT SB_USE <<< "$(free -b | awk '/^Swap:/{print $2,$3}')" | |
| if [[ "${SB_TOT:-0}" -gt 0 ]]; then | |
| SWP_PCT=$(awk "BEGIN{printf \"%d\",($SB_USE/$SB_TOT)*100}") | |
| SWP_USE=$(awk "BEGIN{printf \"%.0f MiB\",$SB_USE/1048576}") | |
| SWP_TOT=$(awk "BEGIN{printf \"%.0f MiB\",$SB_TOT/1048576}") | |
| HAS_SWAP=1 | |
| else | |
| SWP_PCT=0; SWP_USE="0"; SWP_TOT="0"; HAS_SWAP=0 | |
| fi | |
| } | |
| collect_disk() { | |
| read -r DB_TOT DB_USE DB_FRE DISK_PCT <<< \ | |
| "$(df -B1 / | awk 'NR==2{gsub(/%/,"",$5);print $2,$3,$4,$5}' 2>/dev/null)" | |
| # macOS df doesn't support -B1 — fallback | |
| if [[ -z "$DB_TOT" ]] || [[ $OS == "macos" ]]; then | |
| read -r DB_TOT DB_USE DB_FRE DISK_PCT <<< \ | |
| "$(df / | awk 'NR==2{gsub(/%/,"",$5);print $2*512,$3*512,$4*512,$5}' 2>/dev/null)" | |
| fi | |
| DISK_PCT=${DISK_PCT:-0} | |
| DISK_TOT=$(awk "BEGIN{printf \"%.1f GiB\",$DB_TOT/1073741824}") | |
| DISK_USE=$(awk "BEGIN{printf \"%.1f GiB\",$DB_USE/1073741824}") | |
| DISK_FRE=$(awk "BEGIN{printf \"%.1f GiB\",$DB_FRE/1073741824}") | |
| } | |
| collect_net() { | |
| if [[ $OS == "macos" ]]; then | |
| NET_IF=$(route -n get default 2>/dev/null | awk '/interface:/{print $2}') | |
| [[ -z "$NET_IF" ]] && NET_IF=$(netstat -rn 2>/dev/null | awk '/^default/{print $NF;exit}') | |
| else | |
| NET_IF=$(ip route 2>/dev/null | awk '/default/{print $5;exit}') | |
| fi | |
| if [[ -z "$NET_IF" ]]; then | |
| NET_IF="N/A"; NET_IP="N/A"; RX="N/A"; TX="N/A"; return | |
| fi | |
| if [[ $OS == "macos" ]]; then | |
| NET_IP=$(ipconfig getifaddr "$NET_IF" 2>/dev/null || echo "N/A") | |
| # 1-second rx/tx delta via netstat | |
| local s1 s2 | |
| s1=$(netstat -bI "$NET_IF" 2>/dev/null | awk 'NR==2{print $7,$10}') | |
| sleep 1 | |
| s2=$(netstat -bI "$NET_IF" 2>/dev/null | awk 'NR==2{print $7,$10}') | |
| local rx1 tx1 rx2 tx2 | |
| read -r rx1 tx1 <<< "$s1"; read -r rx2 tx2 <<< "$s2" | |
| RX=$(awk "BEGIN{printf \"%.1f KB/s\",($rx2-$rx1)/1024}" 2>/dev/null || echo "N/A") | |
| TX=$(awk "BEGIN{printf \"%.1f KB/s\",($tx2-$tx1)/1024}" 2>/dev/null || echo "N/A") | |
| else | |
| NET_IP=$(ip -4 addr show "$NET_IF" 2>/dev/null \ | |
| | awk '/inet /{gsub(/\/.*/,"",$2);print $2}') | |
| local rx1 tx1 rx2 tx2 | |
| rx1=$(cat /sys/class/net/$NET_IF/statistics/rx_bytes 2>/dev/null) | |
| tx1=$(cat /sys/class/net/$NET_IF/statistics/tx_bytes 2>/dev/null) | |
| sleep 1 | |
| rx2=$(cat /sys/class/net/$NET_IF/statistics/rx_bytes 2>/dev/null) | |
| tx2=$(cat /sys/class/net/$NET_IF/statistics/tx_bytes 2>/dev/null) | |
| RX=$(awk "BEGIN{printf \"%.1f KB/s\",($rx2-$rx1)/1024}") | |
| TX=$(awk "BEGIN{printf \"%.1f KB/s\",($tx2-$tx1)/1024}") | |
| fi | |
| } | |
| collect_procs() { | |
| if [[ $OS == "macos" ]]; then | |
| mapfile -t TOP3 < <( | |
| ps aux -r 2>/dev/null \ | |
| | awk 'NR>1&&NR<=4{print substr($11,1,15),$3,$4}' | |
| ) | |
| else | |
| mapfile -t TOP3 < <( | |
| ps aux --sort=-%cpu 2>/dev/null \ | |
| | awk 'NR>1&&NR<=4{print substr($11,1,15),$3,$4}' | |
| ) | |
| fi | |
| } | |
| collect() { | |
| collect_common | |
| if [[ $OS == "macos" ]]; then | |
| collect_cpu_macos | |
| collect_mem_macos | |
| else | |
| collect_cpu_linux | |
| collect_mem_linux | |
| fi | |
| collect_disk | |
| collect_net | |
| collect_procs | |
| # Temp color | |
| local ti=${TEMP_RAW%.*} | |
| if [[ "$ti" =~ ^[0-9]+$ && $ti -ge 80 ]]; then TEMP_C="$C_RED" | |
| elif [[ "$ti" =~ ^[0-9]+$ && $ti -ge 65 ]]; then TEMP_C="$C_YLW" | |
| elif [[ "$ti" =~ ^[0-9]+$ ]]; then TEMP_C="$C_GRN" | |
| else TEMP_C="$C_DIM"; fi | |
| } | |
| # ── Render ──────────────────────────────────────────────────── | |
| render() { | |
| clear | |
| local FI=63 # full card inner width (total = 65) | |
| local HI=30 # half card inner width (total = 32) | |
| local BW=16 # bar visual width | |
| printf "\n" | |
| # ══ HEADER ══════════════════════════════════════════════════ | |
| ctop $FI | |
| ctitle $FI "TOKYO NIGHT MONITOR" | |
| csep $FI | |
| if [[ $OS == "macos" ]]; then | |
| cline $FI " host" "$HOSTNAME" "$C_DIM" "$C_CYN" | |
| cline $FI " cpu" "$CPU_MODEL" "$C_DIM" "$C_TXT" | |
| else | |
| cline $FI " host" "$HOSTNAME" "$C_DIM" "$C_CYN" | |
| fi | |
| cline $FI " uptime" "$UPTIME" "$C_DIM" "$C_TXT" | |
| cbot $FI | |
| printf "\n" | |
| # ══ ROW 1: THERMAL/CPU ══════════════════════════════════════ | |
| local -a CL CR | |
| CL=() | |
| CL+=("$(ctop $HI)") | |
| if [[ $IS_RPI -eq 1 ]]; then | |
| CL+=("$(ctitle $HI "THERMAL")") | |
| CL+=("$(csep $HI)") | |
| CL+=("$(cline $HI " temp" "${TEMP_RAW}${TEMP_UNIT}" "$C_DIM" "$TEMP_C")") | |
| CL+=("$(cline $HI " arm" "$ARM_FREQ" "$C_DIM" "$C_ORG")") | |
| CL+=("$(cline $HI " gpu" "$GPU_FREQ" "$C_DIM" "$C_PRP")") | |
| CL+=("$(cline $HI " thrt" "$THR_V" "$C_DIM" "$THR_C")") | |
| else | |
| CL+=("$(ctitle $HI "THERMAL")") | |
| CL+=("$(csep $HI)") | |
| CL+=("$(cline $HI " temp" "${TEMP_RAW}${TEMP_UNIT}" "$C_DIM" "$TEMP_C")") | |
| CL+=("$(cemp $HI)") | |
| CL+=("$(cemp $HI)") | |
| CL+=("$(cemp $HI)") | |
| fi | |
| CL+=("$(cbot $HI)") | |
| CR=() | |
| CR+=("$(ctop $HI)") | |
| CR+=("$(ctitle $HI "CPU")") | |
| CR+=("$(csep $HI)") | |
| CR+=("$(cbar $HI " load" "$(bar $CPU_PCT $BW)" $BW $CPU_PCT)") | |
| CR+=("$(cemp $HI)") | |
| CR+=("$(cline $HI " cores" "$CPU_CORES" "$C_DIM" "$C_TXT")") | |
| CR+=("$(cemp $HI)") | |
| CR+=("$(cbot $HI)") | |
| sbs $HI $HI CL CR | |
| printf "\n" | |
| # ══ ROW 2: MEMORY | DISK ════════════════════════════════════ | |
| CL=() | |
| CL+=("$(ctop $HI)") | |
| CL+=("$(ctitle $HI "MEMORY")") | |
| CL+=("$(csep $HI)") | |
| CL+=("$(cbar $HI " ram" "$(bar $RAM_PCT $BW)" $BW $RAM_PCT)") | |
| CL+=("$(cline $HI " ├ used" "$RAM_USE" "$C_DIM" "$C_CYN")") | |
| CL+=("$(cline $HI " └ free" "$RAM_FRE" "$C_DIM" "$C_GRN")") | |
| if [[ $HAS_SWAP -eq 1 ]]; then | |
| CL+=("$(csep $HI)") | |
| CL+=("$(cbar $HI " swap" "$(bar $SWP_PCT $BW)" $BW $SWP_PCT)") | |
| CL+=("$(cline $HI " └ used" "$SWP_USE / $SWP_TOT" "$C_DIM" "$C_YLW")") | |
| fi | |
| CL+=("$(cbot $HI)") | |
| CR=() | |
| CR+=("$(ctop $HI)") | |
| CR+=("$(ctitle $HI "DISK /")") | |
| CR+=("$(csep $HI)") | |
| CR+=("$(cbar $HI " root" "$(bar $DISK_PCT $BW)" $BW $DISK_PCT)") | |
| CR+=("$(cline $HI " ├ used" "$DISK_USE" "$C_DIM" "$C_CYN")") | |
| CR+=("$(cline $HI " ├ free" "$DISK_FRE" "$C_DIM" "$C_GRN")") | |
| CR+=("$(cline $HI " └ total" "$DISK_TOT" "$C_DIM" "$C_DIM")") | |
| if [[ $HAS_SWAP -eq 1 ]]; then | |
| CR+=("$(csep $HI)") | |
| CR+=("$(cemp $HI)") | |
| CR+=("$(cemp $HI)") | |
| fi | |
| CR+=("$(cbot $HI)") | |
| sbs $HI $HI CL CR | |
| printf "\n" | |
| # ══ ROW 3: NETWORK | PROCESSES ══════════════════════════════ | |
| CL=() | |
| CL+=("$(ctop $HI)") | |
| CL+=("$(ctitle $HI "NETWORK")") | |
| CL+=("$(csep $HI)") | |
| CL+=("$(cline $HI " iface" "$NET_IF" "$C_DIM" "$C_TEL")") | |
| CL+=("$(cline $HI " ip" "$NET_IP" "$C_DIM" "$C_CYN")") | |
| CL+=("$(csep $HI)") | |
| CL+=("$(cline $HI " ↓ rx" "$RX" "$C_DIM" "$C_GRN")") | |
| CL+=("$(cline $HI " ↑ tx" "$TX" "$C_DIM" "$C_ORG")") | |
| CL+=("$(cbot $HI)") | |
| local _hdr | |
| printf -v _hdr \ | |
| "${C_BDR}│${RESET} ${C_DIM}%-15s %5s %5s${RESET} ${C_BDR}│${RESET}" \ | |
| "command" "cpu%" "mem%" | |
| CR=() | |
| CR+=("$(ctop $HI)") | |
| CR+=("$(ctitle $HI "PROCESSES")") | |
| CR+=("$(csep $HI)") | |
| CR+=("$_hdr") | |
| for entry in "${TOP3[@]}"; do | |
| local cmd cpu mem | |
| read -r cmd cpu mem <<< "$entry" | |
| local _row | |
| printf -v _row \ | |
| "${C_BDR}│${RESET} ${C_CYN}%-15s${RESET} ${C_YLW}%5s${RESET} ${C_GRN}%5s${RESET} ${C_BDR}│${RESET}" \ | |
| "${cmd:0:15}" "${cpu:0:5}" "${mem:0:5}" | |
| CR+=("$_row") | |
| done | |
| while [[ ${#CR[@]} -lt ${#CL[@]}-1 ]]; do CR+=("$(cemp $HI)"); done | |
| CR+=("$(cbot $HI)") | |
| sbs $HI $HI CL CR | |
| # ── Footer ────────────────────────────────────────────────── | |
| local os_tag="linux" | |
| [[ $OS == "macos" ]] && os_tag="macos" | |
| [[ $IS_RPI -eq 1 ]] && os_tag="rpi" | |
| printf "\n ${C_DIM}%s · %s ${RESET}${C_YLW}ctrl+c${RESET}${C_DIM} to exit${RESET}\n\n" \ | |
| "$os_tag" "$NOW" | |
| } | |
| # ── Entry ───────────────────────────────────────────────────── | |
| trap 'tput cnorm; printf "\n"; exit 0' INT TERM | |
| tput civis | |
| if [[ "$1" == "--watch" || "$1" == "-w" ]]; then | |
| INTERVAL="${2:-5}" | |
| while true; do collect; render; sleep "$INTERVAL"; done | |
| else | |
| collect; render; tput cnorm | |
| fi |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use
Install
brew install osx-cpu-tempfor mac