Files
dotfiles/.local/bin/myfetch.sh
T

114 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Colors
cyan=$'\e[1;36m'; green=$'\e[1;32m'; red=$'\e[1;31m'
magenta=$'\e[1;35m'; blue=$'\e[1;34m'
reset=$'\e[0m'
# Box drawing chars (UTF-8 fallback safe)
tl="╭"; tr="╮"; bl="╰"; br="╯"; h="─"; v="│"
if ! locale charmap 2>/dev/null | grep -qi 'utf'; then
tl="+"; tr="+"; bl="+"; br="+"; h="-"; v="|"
fi
# Strip ANSI escapes
strip_colors() { printf '%s' "$1" | sed -r 's/\x1B\[[0-9;]*[mK]//g'; }
# --- Collect stats ---
# CPU (cores/threads)
if command -v lscpu >/dev/null; then
sockets=$(lscpu | awk -F: '/Socket\(s\)/{gsub(/ /,"");print $2;exit}')
cores_per=$(lscpu | awk -F: '/Core\(s\) per socket/{gsub(/ /,"");print $2;exit}')
physical_cores=$((sockets * cores_per))
else
physical_cores=$(grep -E 'cpu cores' /proc/cpuinfo | head -1 | awk '{print $4}')
fi
logical_threads=$(nproc --all)
# CPU usage (quick sample)
cpu_usage() {
read -r _ u n s i _ < <(grep '^cpu ' /proc/stat)
prev=$((u+n+s+i)); prev_idle=$i
sleep 0.1
read -r _ u n s i _ < <(grep '^cpu ' /proc/stat)
cur=$((u+n+s+i)); idle=$i
dt=$((cur - prev)); di=$((idle - prev_idle))
((dt>0)) && printf "%.1f%%" "$(bc -l <<< "100*($dt-$di)/$dt")" || echo "0.0%"
}
# Time since last system update
since_update() {
days_since_update=0
if [[ -f ~/.last_world_update ]]; then
last_epoch=$(stat -c %Y ~/.last_world_update)
days_since_update=$(( ( $(date +%s) - last_epoch ) / 86400 ))
fi
echo $days_since_update
}
cpu_use=$(cpu_usage)
# Memory
mem_usage=$(free -h | awk '/Mem:/ {print $3 "/" $2}')
# System age
sys_age=$(( ( $(date +%s) - $(stat -c %W / 2>/dev/null || echo 0) ) / 86400 ))
# Packages
pkg_count=$(find /var/db/pkg -mindepth 2 -maxdepth 2 -type d 2>/dev/null | wc -l)
# Days since last update
days_update=$(since_update)
# --- Define lines (easy to add new ones) ---
lines=(
"${cyan}CPU${reset}: ${physical_cores}c/${logical_threads}t/${cpu_use}"
"${green}Memory${reset}: ${mem_usage}"
"${magenta}Age${reset}: ${sys_age} days"
"${blue}Pkgs${reset}: ${pkg_count}"
"${red}Update${reset}: ${days_update}"
)
# --- Compute max width ---
maxlen=0
for l in "${lines[@]}"; do
stripped=$(strip_colors "$l")
slen=${#stripped}
((slen > maxlen)) && maxlen=$slen
done
# --- Borders ---
hline=$(printf "%${maxlen}s" "" | sed "s/ /$h/g")
printf '%s%s%s\n' "$tl" "$hline" "$tr"
# # --- Content ---
# for l in "${lines[@]}"; do
# stripped=$(strip_colors "$l")
# pad=$((maxlen - ${#stripped}))
# printf '%s%s%*s%s\n' "$v" "$l" "$pad" "" "$v"
# done
# --- Content with right-aligned values ---
for l in "${lines[@]}"; do
# split into label and value at first colon
label="${l%%:*}:" # label including colon
value="${l#*: }" # everything after colon + space
# strip colors for length calculation
stripped_label=$(strip_colors "$label")
stripped_value=$(strip_colors "$value")
# compute padding: value is right-aligned
label_len=${#stripped_label}
value_len=${#stripped_value}
pad=$((maxlen - label_len - value_len))
# print line: label left, pad spaces, value right
printf '%s%s%*s%s%s\n' "$v" "$label" "$pad" "" "$value" "$v"
done
# --- Bottom ---
printf '%s%s%s\n' "$bl" "$hline" "$br"