Files
RetroDebian/neofetch
2026-03-22 18:48:22 +01:00

675 lines
15 KiB
Bash

#!/bin/bash
VERSION="0.2-retrodebian"
PATH=$PATH:/usr/sbin:/sbin
LC_ALL=C
LANG=C
USE_COLOR=1
SHOW_ASCII=1
ESC="$(printf '\033')"
C_RESET="${ESC}[0m"
C_BOLD="${ESC}[1m"
C_RED="${ESC}[31m"
C_BLUE="${ESC}[34m"
C_WHITE="${ESC}[37m"
C_GREEN="${ESC}[32m"
C_BGREEN="${ESC}[1;32m"
C_CYAN="${ESC}[36m"
if [ "$USE_COLOR" != "1" ]; then
C_RESET=""
C_BOLD=""
C_RED=""
C_BLUE=""
C_WHITE=""
fi
trim() {
echo "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
}
strip_ansi() {
echo "$1" | sed 's/'"$ESC"'\\[[0-9;]*m//g'
}
repeat_char() {
ch="$1"
count="$2"
out=""
while [ "$count" -gt 0 ] 2>/dev/null; do
out="${out}${ch}"
count="$(expr "$count" - 1)"
done
echo "$out"
}
get_term_cols() {
TERM_COLS=80
if type tput >/dev/null 2>&1; then
cols="$(tput cols 2>/dev/null)"
case "$cols" in
''|*[!0-9]*)
;;
*)
if [ "$cols" -gt 0 ] 2>/dev/null; then
TERM_COLS="$cols"
return
fi
;;
esac
fi
if type stty >/dev/null 2>&1; then
cols="$(stty size 2>/dev/null | awk '{print $2}')"
case "$cols" in
''|*[!0-9]*)
;;
*)
if [ "$cols" -gt 0 ] 2>/dev/null; then
TERM_COLS="$cols"
return
fi
;;
esac
fi
}
get_user_host() {
if [ -n "$USER" ]; then
F_USER="$USER"
else
F_USER="$(id -un 2>/dev/null)"
fi
if [ -z "$F_USER" ]; then
F_USER="user"
fi
F_HOST="$(hostname 2>/dev/null)"
if [ -z "$F_HOST" ]; then
F_HOST="host"
fi
F_TITLE="${C_RED}${C_BOLD}${F_USER}${C_RESET}@${C_RED}${C_BOLD}${F_HOST}${C_RESET}"
}
get_os() {
F_OS="Linux"
if [ -f /etc/debian_version ]; then
debv="$(cat /etc/debian_version 2>/dev/null)"
debv="$(trim "$debv")"
if [ -f /etc/issue ]; then
issue="$(head -n 1 /etc/issue 2>/dev/null)"
issue="$(echo "$issue" | sed 's/\\n//g; s/\\l//g')"
issue="$(trim "$issue")"
case "$issue" in
Debian*|Ubuntu*)
F_OS="$issue"
;;
*)
if [ -n "$debv" ]; then
F_OS="Debian GNU/Linux $debv"
else
F_OS="Debian GNU/Linux"
fi
;;
esac
else
if [ -n "$debv" ]; then
F_OS="Debian GNU/Linux $debv"
else
F_OS="Debian GNU/Linux"
fi
fi
fi
arch="$(uname -m 2>/dev/null)"
arch="$(trim "$arch")"
if [ -n "$arch" ]; then
F_OS="${F_OS} ${arch}"
fi
}
get_host_model() {
F_HOSTMODEL=""
if [ -r /sys/devices/virtual/dmi/id/board_vendor ] || [ -r /sys/devices/virtual/dmi/id/board_name ]; then
bv="$(cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null)"
bn="$(cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null)"
F_HOSTMODEL="$(trim "$bv $bn")"
fi
if [ -z "$F_HOSTMODEL" ] && [ -r /sys/devices/virtual/dmi/id/product_name ]; then
pn="$(cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null)"
pv="$(cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null)"
F_HOSTMODEL="$(trim "$pn $pv")"
fi
}
get_kernel() {
ks="$(uname -s 2>/dev/null)"
kr="$(uname -r 2>/dev/null)"
F_KERNEL="$(trim "$ks $kr")"
}
get_uptime() {
F_UPTIME=""
if [ -r /proc/uptime ]; then
secs="$(awk '{print int($1)}' /proc/uptime 2>/dev/null)"
if [ -n "$secs" ]; then
d="$(expr "$secs" / 86400)"
h="$(expr \( "$secs" % 86400 \) / 3600)"
m="$(expr \( "$secs" % 3600 \) / 60)"
out=""
if [ "$d" -gt 0 ] 2>/dev/null; then
if [ "$d" -eq 1 ] 2>/dev/null; then
out="1 day"
else
out="$d days"
fi
fi
if [ "$h" -gt 0 ] 2>/dev/null; then
if [ -n "$out" ]; then
out="${out}, "
fi
if [ "$h" -eq 1 ] 2>/dev/null; then
out="${out}1 hour"
else
out="${out}${h} hours"
fi
fi
if [ "$m" -gt 0 ] 2>/dev/null; then
if [ -n "$out" ]; then
out="${out}, "
fi
out="${out}${m} min"
fi
if [ -z "$out" ]; then
out="${secs} sec"
fi
F_UPTIME="$out"
fi
fi
}
get_packages() {
F_PACKAGES=""
if type dpkg-query >/dev/null 2>&1; then
cnt="$(dpkg-query -W -f='x\n' 2>/dev/null | wc -l | awk '{print $1}')"
cnt="$(trim "$cnt")"
if [ -n "$cnt" ]; then
F_PACKAGES="$cnt (dpkg)"
fi
fi
}
get_shell() {
F_SHELL=""
shn="$SHELL"
if [ -z "$shn" ]; then
shn="/bin/sh"
fi
base="$(basename "$shn" 2>/dev/null)"
if [ -z "$base" ]; then
base="sh"
fi
F_SHELL="$base"
case "$base" in
bash)
if [ -n "$BASH_VERSION" ]; then
bv="$(echo "$BASH_VERSION" | sed 's/-.*//')"
F_SHELL="$base $bv"
fi
;;
esac
}
get_resolution() {
F_RESOLUTION=""
if [ -n "$DISPLAY" ]; then
if type xrandr >/dev/null 2>&1; then
F_RESOLUTION="$(xrandr 2>/dev/null | awk '
/ connected/ && /[0-9]+x[0-9]+/ {
for (i = 1; i <= NF; i++) {
if ($i ~ /[0-9]+x[0-9]+\+/) {
gsub(/\+.*/, "", $i)
print $i
exit
}
}
}
')"
fi
if [ -z "$F_RESOLUTION" ] && type xdpyinfo >/dev/null 2>&1; then
F_RESOLUTION="$(xdpyinfo 2>/dev/null | awk '/dimensions:/ {print $2; exit}')"
fi
fi
}
get_de() {
F_DE=""
if [ -n "$DESKTOP_SESSION" ]; then
F_DE="$DESKTOP_SESSION"
elif [ -n "$XDG_CURRENT_DESKTOP" ]; then
F_DE="$XDG_CURRENT_DESKTOP"
elif [ -n "$GNOME_DESKTOP_SESSION_ID" ]; then
F_DE="GNOME"
elif [ -n "$KDE_FULL_SESSION" ]; then
F_DE="KDE"
fi
case "$F_DE" in
gnome*|GNOME*)
F_DE="GNOME"
;;
xfce*|XFCE*)
F_DE="Xfce"
;;
lxde*|LXDE*)
F_DE="LXDE"
;;
kde*|KDE*)
F_DE="KDE"
;;
fluxbox*|Fluxbox*)
F_DE="Fluxbox"
;;
openbox*|Openbox*)
F_DE="Openbox"
;;
esac
}
get_wm() {
F_WM=""
if [ -n "$DISPLAY" ]; then
if type xprop >/dev/null 2>&1; then
wid="$(xprop -root _NET_SUPPORTING_WM_CHECK 2>/dev/null | awk '{print $NF}')"
if [ -n "$wid" ]; then
F_WM="$(xprop -id "$wid" -f _NET_WM_NAME 8t _NET_WM_NAME 2>/dev/null | sed 's/.*= //' | sed 's/^"//' | sed 's/"$//')"
fi
fi
if [ -z "$F_WM" ]; then
F_WM="$(ps -e 2>/dev/null | egrep 'fluxbox|openbox|xfwm4|metacity|kwin|icewm|fvwm|blackbox|enlightenment' | head -n 1 | awk '{print $NF}')"
fi
fi
}
get_cpu() {
F_CPU=""
F_CPU_NAME=""
cpu=""
speed=""
cores=""
if [ -r /proc/cpuinfo ]; then
cpu="$(awk -F ': ' '
/model name/ { print $2; exit }
/cpu[[:space:]]*:/ { print $2; exit }
/Hardware/ { print $2; exit }
/Processor/ { print $2; exit }
' /proc/cpuinfo 2>/dev/null)"
speed="$(awk -F ': ' '/cpu MHz/ { printf "%d", $2; exit }' /proc/cpuinfo 2>/dev/null)"
cores="$(grep -c '^processor' /proc/cpuinfo 2>/dev/null)"
fi
cpu="$(trim "$cpu")"
cpu="$(echo "$cpu" | sed 's/(TM)//g; s/(R)//g; s/ */ /g')"
cpu="$(trim "$cpu")"
if [ -n "$cpu" ]; then
F_CPU_NAME="$cpu"
fi
out="$cpu"
if [ -n "$cores" ] && [ -n "$out" ]; then
out="${out} (${cores})"
fi
if [ -n "$speed" ] && [ -n "$out" ]; then
if [ "$speed" -ge 1000 ] 2>/dev/null; then
ghz_major="$(expr "$speed" / 1000)"
ghz_minor="$(expr \( "$speed" % 1000 \) / 100)"
out="${out} @ ${ghz_major}.${ghz_minor}GHz"
else
out="${out} @ ${speed}MHz"
fi
fi
F_CPU="$out"
}
get_gpu() {
F_GPU=""
if type lspci >/dev/null 2>&1; then
F_GPU="$(lspci 2>/dev/null | egrep 'VGA compatible controller|Display controller|3D controller' | head -n 1 | sed 's/^[0-9A-Fa-f:.]* //')"
F_GPU="$(trim "$F_GPU")"
F_GPU="$(echo "$F_GPU" | sed 's/Corporation//g; s/ Inc\.//g; s/\[//g; s/\]//g; s/ */ /g')"
F_GPU="$(trim "$F_GPU")"
fi
}
get_memory() {
F_MEMORY=""
mem_total=0
mem_free=0
mem_buffers=0
mem_cached=0
mem_avail=0
if [ -r /proc/meminfo ]; then
while read a b c; do
case "$a" in
MemTotal:) mem_total="$b" ;;
MemFree:) mem_free="$b" ;;
Buffers:) mem_buffers="$b" ;;
Cached:) mem_cached="$b" ;;
MemAvailable:) mem_avail="$b" ;;
esac
done < /proc/meminfo
fi
if [ "$mem_total" -gt 0 ] 2>/dev/null; then
if [ "$mem_avail" -gt 0 ] 2>/dev/null; then
mem_used="$(expr "$mem_total" - "$mem_avail")"
else
mem_used="$(expr "$mem_total" - "$mem_free" - "$mem_buffers" - "$mem_cached")"
fi
mem_used_mib="$(expr "$mem_used" / 1024)"
mem_total_mib="$(expr "$mem_total" / 1024)"
F_MEMORY="${mem_used_mib} MiB / ${mem_total_mib} MiB"
fi
}
get_swap() {
F_SWAP=""
swap_total=0
swap_free=0
if [ -r /proc/meminfo ]; then
while read a b c; do
case "$a" in
SwapTotal:) swap_total="$b" ;;
SwapFree:) swap_free="$b" ;;
esac
done < /proc/meminfo
fi
if [ "$swap_total" -gt 0 ] 2>/dev/null; then
swap_used="$(expr "$swap_total" - "$swap_free")"
swap_used_mib="$(expr "$swap_used" / 1024)"
swap_total_mib="$(expr "$swap_total" / 1024)"
F_SWAP="${swap_used_mib} MiB / ${swap_total_mib} MiB"
fi
}
get_root_disk() {
F_DISK=""
if type df >/dev/null 2>&1; then
F_DISK="$(df -hP / 2>/dev/null | awk 'NR == 2 { print $3 " / " $2 " (" $5 "), " $4 " free" }')"
F_DISK="$(trim "$F_DISK")"
fi
}
build_ascii_block() {
out="$1"
: > "$out"
if [ "$SHOW_ASCII" != "1" ]; then
return
fi
cat > "$out" <<EOF
${C_RED} _,met\$\$\$\$\$gg.
${C_RED} ,g\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$P.
${C_RED} ,g\$\$P" """Y\$\$.".
${C_RED} ,\$\$P' \`\$\$\$.
${C_RED}',\$\$P ,ggs. \`\$\$b:
${C_RED}\`d\$\$' ,\$P"' . \$\$\$
${C_RED} \$\$P d\$' , \$\$P
${C_RED} \$\$: \$\$. - ,d\$\$'
${C_RED} \$\$; Y\$b._ _,d\$P'
${C_RED} Y\$\$. \`.\`"Y\$\$\$\$P"'
${C_RED} \`\$\$b "-.__
${C_RED} \`Y\$\$
${C_RED} \`Y\$\$.
${C_RED} \`\$\$b.
${C_RED} \`Y\$\$b.
${C_RED} \`"Y\$b._
${C_RED} \`""""${C_RESET}
${C_GREEN} RetroDebian${C_RESET}
EOF
}
write_info_line() {
file="$1"
key="$2"
val="$3"
if [ -n "$val" ]; then
echo "${C_CYAN}${C_BOLD}${key}${C_RESET}: $val" >> "$file"
fi
}
build_info_block() {
out="$1"
: > "$out"
echo "$F_TITLE" >> "$out"
title_plain="$(strip_ansi "$F_TITLE")"
title_len="$(echo "$title_plain" | awk '{print length($0)}')"
underline="$(repeat_char "-" "$title_len")"
echo "$underline" >> "$out"
echo "" >> "$out"
write_info_line "$out" "OS" "$F_OS"
write_info_line "$out" "RetroDebian" "$F_RETRODEBIAN"
write_info_line "$out" "Host" "$F_HOSTMODEL"
write_info_line "$out" "Kernel" "$F_KERNEL"
write_info_line "$out" "Uptime" "$F_UPTIME"
write_info_line "$out" "Packages" "$F_PACKAGES"
write_info_line "$out" "Shell" "$F_SHELL"
write_info_line "$out" "Resolution" "$F_RESOLUTION"
write_info_line "$out" "DE" "$F_DE"
write_info_line "$out" "WM" "$F_WM"
write_info_line "$out" "CPU" "$F_CPU"
write_info_line "$out" "GPU" "$F_GPU"
write_info_line "$out" "Memory" "$F_MEMORY"
write_info_line "$out" "Swap" "$F_SWAP"
write_info_line "$out" "Disk" "$F_DISK"
}
render_output() {
left="/tmp/retrodebian-fetch-left.$$"
right="/tmp/retrodebian-fetch-right.$$"
trap 'rm -f "$left" "$right"' 0 1 2 3 15
build_ascii_block "$left"
build_info_block "$right"
get_term_cols
if [ "$SHOW_ASCII" = "1" ] && [ "$TERM_COLS" -ge 76 ] 2>/dev/null; then
left_width="$(awk '
{
n = length($0)
if (n > max) {
max = n
}
}
END {
if (max < 1) {
max = 1
}
print max
}
' "$left")"
gap=3
pad_width="$(expr "$left_width" + "$gap")"
exec 3<"$left"
exec 4<"$right"
left_done=0
right_done=0
while :; do
if [ "$left_done" -eq 0 ]; then
if IFS= read -r l <&3; then
:
else
l=""
left_done=1
fi
else
l=""
fi
if [ "$right_done" -eq 0 ]; then
if IFS= read -r r <&4; then
:
else
r=""
right_done=1
fi
else
r=""
fi
if [ "$left_done" -eq 1 ] && [ "$right_done" -eq 1 ] && [ -z "$l" ] && [ -z "$r" ]; then
break
fi
printf "%-${pad_width}s%s\n" "$l" "$r"
done
exec 3<&-
exec 4<&-
else
if [ "$SHOW_ASCII" = "1" ]; then
cat "$left"
echo ""
fi
cat "$right"
fi
rm -f "$left" "$right"
trap - 0 1 2 3 15
}
usage() {
echo "retrodebian-fetch $VERSION"
echo "Usage: $0 [--stdout] [--off] [--help] [--version]"
exit 0
}
parse_args() {
while [ -n "$1" ]; do
case "$1" in
--stdout)
USE_COLOR=0
SHOW_ASCII=0
C_RESET=""
C_BOLD=""
C_RED=""
C_BLUE=""
C_WHITE=""
;;
--off)
SHOW_ASCII=0
;;
--help)
usage
;;
--version)
echo "$VERSION"
exit 0
;;
esac
shift
done
}
main() {
parse_args "$@"
get_user_host
get_os
get_host_model
get_kernel
get_uptime
get_packages
get_shell
get_resolution
get_de
get_wm
get_cpu
get_gpu
get_memory
get_swap
get_root_disk
render_output
}
main "$@"