Skip to content

Instantly share code, notes, and snippets.

@cheeseonamonkey
Created December 6, 2025 07:50
Show Gist options
  • Select an option

  • Save cheeseonamonkey/c58a35687dddb1a574b32e3c7b198fb9 to your computer and use it in GitHub Desktop.

Select an option

Save cheeseonamonkey/c58a35687dddb1a574b32e3c7b198fb9 to your computer and use it in GitHub Desktop.
custom fetch
#!/usr/bin/env zsh
# Custom fetch script (zsh only)
# - jp2a image (color, more detail)
# - 2-column layout: system (left), misc/fun stats (right)
set -u
set +x 2>/dev/null || true # disable xtrace so lv/rv lines don't print
# -------------------- Colors / formatting --------------------
C_LABEL=$'\033[1;34m'
C_RESET=$'\033[0m'
SEP=" -> "
have() { command -v "$1" >/dev/null 2>&1; }
bar() {
local cur=$1 max=$2 len=27
(( max <= 0 )) && { printf "[---------------------------] 0%%"; return; }
(( cur < 0 )) && cur=0
(( cur > max )) && cur=max
local pct=$(( 100 * cur / max ))
local fill=$(( pct * len / 100 ))
(( fill < 0 )) && fill=0
(( fill > len )) && fill=len
printf '['
printf "%${fill}s" | tr ' ' '#'
printf "%$((len-fill))s" | tr ' ' '='
printf '] %d%%' "$pct"
}
# -------------------- System collectors ----------------------
os_name() {
if [ -r /etc/os-release ]; then
awk -F= '/^PRETTY_NAME=/{gsub("\"","");print $2}' /etc/os-release
else
uname -sr
fi
}
de_name() {
[ -n "${XDG_CURRENT_DESKTOP:-}" ] && printf "%s" "$XDG_CURRENT_DESKTOP" || printf "?"
}
wm_name() {
if have wmctrl; then
wmctrl -m 2>/dev/null | awk -F: '/Name/{print $2}' | xargs
elif have xprop; then
xprop -root _NET_SUPPORTING_WM_CHECK 2>/dev/null |
awk '{print $NF}' |
xargs -I{} xprop -id {} _NET_WM_NAME 2>/dev/null |
awk -F\" '/_NET_WM_NAME/ {print $2}'
else
printf "?"
fi
}
os_de_wm() {
printf "%s / %s / %s" "$(os_name)" "$(de_name)" "$(wm_name)"
}
shell_term() {
local sh t
sh=$(basename -- "${SHELL:-sh}")
t="${TERM:-?}"
printf "%s / %s" "$sh" "$t"
}
memory_bar() {
local total avail used
total=$(awk '/MemTotal/{print $2}' /proc/meminfo 2>/dev/null)
avail=$(awk '/MemAvailable/{print $2}' /proc/meminfo 2>/dev/null)
if [ -z "${total:-}" ] || [ -z "${avail:-}" ]; then
printf "n/a"
return
fi
used=$((total - avail)) # kB
bar "$used" "$total"
}
disk_bar() {
local used total
used=$(df -B1 / 2>/dev/null | awk 'NR==2{print $3}')
total=$(df -B1 / 2>/dev/null | awk 'NR==2{print $2}')
if [ -z "${used:-}" ] || [ -z "${total:-}" ]; then
printf "n/a"
return
fi
bar "$used" "$total"
}
battery_bar() {
local cap
for cap in /sys/class/power_supply/BAT*/capacity; do
if [ -r "$cap" ]; then
local c; c=$(cat "$cap" 2>/dev/null)
case "$c" in
''|*[!0-9]*) printf "n/a" ;;
*) bar "$c" 100 ;;
esac
return
fi
done
printf "n/a"
}
network_info() {
if ! have ip; then
printf "ip(8) missing"
return
fi
ip -brief addr 2>/dev/null | awk '/UP/{print $1":"$3}' | paste -sd' ' -
}
local_ip() {
if have ip; then
ip route get 8.8.8.8 2>/dev/null | awk '/src/{print $7}' | head -n1
else
printf "?"
fi
}
song_info() {
if have playerctl; then
playerctl metadata --format '{{title}} ({{artist}})' 2>/dev/null ||
printf "none"
else
printf "none"
fi
}
# -------------------- Fun stats (with cache) -----------------
FUN_CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/fetch"
mkdir -p "$FUN_CACHE" 2>/dev/null || true
_ts() { date +%s; }
memo() {
local key="$1" ttl="$2"; shift 2
local file="$FUN_CACHE/$key"
local now mt
now=$(_ts)
if [ -f "$file" ]; then
mt=$(stat -c %Y "$file" 2>/dev/null || echo 0)
if [ "$((now - mt))" -lt "$ttl" ] 2>/dev/null; then
cat "$file"
return
fi
fi
local val
val="$("$@")"
printf "%s" "$val" >"$file"
printf "%s" "$val"
}
boot_count() {
if have journalctl; then
journalctl --no-pager --list-boots 2>/dev/null | wc -l
else
printf "?"
fi
}
reboot_events() {
if have journalctl; then
journalctl --no-pager -g 'reboot\|shutdown' 2>/dev/null | wc -l
else
printf "?"
fi
}
wifi_seen() {
local dir="/etc/NetworkManager/system-connections"
[ -d "$dir" ] || { printf "0"; return; }
find "$dir" -type f 2>/dev/null |
xargs grep -F 'ssid=' 2>/dev/null |
wc -l
}
pkg_installs() {
zgrep -h " install " /var/log/dpkg.log* 2>/dev/null | wc -l
}
pkg_upgrades() {
zgrep -h " upgrade " /var/log/dpkg.log* 2>/dev/null | wc -l
}
sudo_uses() {
if have journalctl; then
journalctl _COMM=sudo --no-pager 2>/dev/null | wc -l
else
printf "?"
fi
}
session_events() {
if have journalctl; then
journalctl --no-pager 2>/dev/null |
grep -Ei 'session (opened|closed)' |
wc -l
else
printf "?"
fi
}
failed_logins() {
local log="/var/log/btmp"
if ! have lastb || [ ! -r "$log" ]; then
printf "?"
return
fi
lastb 2>/dev/null | wc -l
}
boots_stat() { memo boots 86400 boot_count; }
reboots_stat() { memo reboots 86400 reboot_events; }
wifi_stat() { memo wifi 86400 wifi_seen; }
pkg_installs_stat() { memo pins 86400 pkg_installs; }
pkg_upgrades_stat() { memo pugs 86400 pkg_upgrades; }
sudo_uses_stat() { memo sudo 86400 sudo_uses; }
session_events_stat() { memo sess 86400 session_events; }
failed_logins_stat() { memo flog 86400 failed_logins; }
# -------------------- Image (jp2a, color) -------------------
print_image() {
local img="${1:-$HOME/bin/fetchLogo.png}"
[ -r "$img" ] || return
if ! have jp2a; then
return
fi
local cols=${COLUMNS:-80}
local width=$((cols / 2))
(( width < 20 )) && width=20
# Colorized, dark-background friendly jp2a output
jp2a --width="$width" --colors --background=dark "$img"
printf '\n'
}
# -------------------- Layout: header + 2 columns ------------
print_header() {
local user host
user=${USER:-$(whoami 2>/dev/null || echo "?")}
host=$(hostname 2>/dev/null || echo "?")
printf "%s%s@%s%s\n" "$C_LABEL" "$user" "$host" "$C_RESET"
printf "%0.s=" {1..40}
printf '\n'
}
print_rows() {
local -a left_labels left_funcs right_labels right_funcs
left_labels=(
"OS / DE / WM"
"Shell / Terminal"
"Memory"
"Disk (/)"
"Battery"
"Network"
"Local IP"
"Song"
)
left_funcs=(
os_de_wm
shell_term
memory_bar
disk_bar
battery_bar
network_info
local_ip
song_info
)
right_labels=(
"Boots"
"Reboots+Shutdowns"
"WiFi networks"
"Pkg installs"
"Pkg upgrades"
"Sudo uses"
"Sessions"
"Failed logins"
)
right_funcs=(
boots_stat
reboots_stat
wifi_stat
pkg_installs_stat
pkg_upgrades_stat
sudo_uses_stat
session_events_stat
failed_logins_stat
)
local n_left=${#left_labels}
local n_right=${#right_labels}
local max_rows=$(( n_left > n_right ? n_left : n_right ))
local cols=${COLUMNS:-120}
local left_width=$(( cols / 2 ))
(( left_width < 40 )) && left_width=40
local i
for (( i = 1; i <= max_rows; ++i )); do
local l="" r=""
if (( i <= n_left )); then
local lv
lv="$("${left_funcs[i]}")"
l="${C_LABEL}${left_labels[i]}${C_RESET}${SEP}${lv}"
fi
if (( i <= n_right )); then
local rv
rv="$("${right_funcs[i]}")"
r="${C_LABEL}${right_labels[i]}:${C_RESET} ${rv}"
fi
if [[ -n "$l" || -n "$r" ]]; then
printf "%-*s" "$left_width" "$l"
if [[ -n "$r" ]]; then
printf " %s" "$r"
fi
printf '\n'
fi
done
}
# -------------------- Main ----------------------------------
main() {
print_image
print_header
print_rows
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment