Skip to content

Instantly share code, notes, and snippets.

@hed0rah
Created March 21, 2026 19:07
Show Gist options
  • Select an option

  • Save hed0rah/e671338b8f3076cb6c5688232f13b296 to your computer and use it in GitHub Desktop.

Select an option

Save hed0rah/e671338b8f3076cb6c5688232f13b296 to your computer and use it in GitHub Desktop.
system profile dump
#!/bin/bash
# =============================================================
# sysprofile — Deep system profile dump
#
# Generates a comprehensive plain-text snapshot of a Linux box.
# Designed to be pasted into AI conversations for full context.
#
# Covers: hardware, kernel, storage, network, GPU, thermal,
# users, services, packages, dev tools, containers, firewalls,
# conda/python/node environments, cron, logs, and more.
#
# Usage:
# sysprofile # Full dump to stdout
# sysprofile --save # Save to ~/sysprofile-<date>.txt
# sysprofile --section hw # Run single section
# sysprofile --list # List available sections
# sysprofile --compact # Shorter output, skip large dumps
#
# Sections: hw cpu mem gpu disk net thermal kernel users
# services firewall pkg dev python conda node
# rust docker containers gpu_proc cron env
# logs dirs perf usb pci bt audio
# =============================================================
set -uo pipefail
VERSION="1.0.0"
COMPACT=false
SAVE=false
SECTION_FILTER=""
OUTPUT=""
DIVIDER="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Parse args
while [[ $# -gt 0 ]]; do
case "$1" in
--compact) COMPACT=true; shift ;;
--save) SAVE=true; shift ;;
--section) SECTION_FILTER="$2"; shift 2 ;;
--list)
echo "Available sections:"
echo " hw cpu mem gpu disk net thermal kernel users services"
echo " firewall pkg dev python conda node rust docker containers"
echo " gpu_proc cron env logs dirs perf usb pci audio sysctl"
exit 0 ;;
--help|-h)
head -20 "$0" | grep "^#" | sed 's/^# *//'
exit 0 ;;
*) echo "Unknown arg: $1"; exit 1 ;;
esac
done
# Collect output in variable for optional save
emit() { OUTPUT+="$1"$'\n'; echo "$1"; }
section() { emit ""; emit "$DIVIDER"; emit " $1"; emit "$DIVIDER"; }
sub() { emit ""; emit "── $1 ──"; }
kv() { printf -v line " %-24s %s" "$1:" "$2"; emit "$line"; }
run() { eval "$@" 2>/dev/null || echo " [not available]"; }
should_run() {
[[ -z "$SECTION_FILTER" ]] || [[ "$SECTION_FILTER" == "$1" ]]
}
# ═══════════════════════════════════════════════════════════════
# Header
# ═══════════════════════════════════════════════════════════════
emit ""
emit " SYSTEM PROFILE — $(hostname) — $(date '+%Y-%m-%d %H:%M:%S %Z')"
emit " sysprofile v${VERSION} $([ "$COMPACT" = true ] && echo '[compact mode]' || echo '[full mode]')"
emit ""
# ═══════════════════════════════════════════════════════════════
if should_run hw; then
section "HARDWARE OVERVIEW"
kv "Hostname" "$(hostname)"
kv "Machine ID" "$(cat /etc/machine-id 2>/dev/null || echo 'n/a')"
if [ -f /sys/class/dmi/id/product_name ]; then
kv "Product" "$(cat /sys/class/dmi/id/product_name 2>/dev/null) $(cat /sys/class/dmi/id/product_version 2>/dev/null)"
kv "Manufacturer" "$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null)"
kv "BIOS" "$(cat /sys/class/dmi/id/bios_vendor 2>/dev/null) $(cat /sys/class/dmi/id/bios_version 2>/dev/null) ($(cat /sys/class/dmi/id/bios_date 2>/dev/null))"
fi
if command -v dmidecode &>/dev/null && [ "$(id -u)" -eq 0 ]; then
CHASSIS=$(dmidecode -s chassis-type 2>/dev/null)
[ -n "$CHASSIS" ] && kv "Chassis" "$CHASSIS"
fi
kv "Architecture" "$(uname -m)"
kv "Uptime" "$(uptime -p 2>/dev/null || uptime)"
kv "Boot time" "$(who -b 2>/dev/null | awk '{print $3, $4}')"
kv "Current user" "$(whoami) (uid $(id -u))"
fi
# ═══════════════════════════════════════════════════════════════
if should_run cpu; then
section "CPU"
CPU_MODEL=$(lscpu 2>/dev/null | grep "Model name" | sed 's/.*: *//')
CPU_CORES=$(lscpu 2>/dev/null | grep "^CPU(s):" | awk '{print $2}')
CPU_THREADS=$(nproc 2>/dev/null)
CPU_SOCKETS=$(lscpu 2>/dev/null | grep "Socket(s)" | awk '{print $2}')
CPU_CORES_PER=$(lscpu 2>/dev/null | grep "Core(s) per" | awk '{print $4}')
CPU_MAX=$(lscpu 2>/dev/null | grep "CPU max MHz" | awk '{printf "%.1f GHz", $NF/1000}')
CPU_MIN=$(lscpu 2>/dev/null | grep "CPU min MHz" | awk '{printf "%.1f GHz", $NF/1000}')
CPU_ARCH=$(lscpu 2>/dev/null | grep "Architecture" | awk '{print $2}')
CPU_CACHE_L1D=$(lscpu 2>/dev/null | grep "L1d cache" | sed 's/.*: *//')
CPU_CACHE_L1I=$(lscpu 2>/dev/null | grep "L1i cache" | sed 's/.*: *//')
CPU_CACHE_L2=$(lscpu 2>/dev/null | grep "L2 cache" | sed 's/.*: *//')
CPU_CACHE_L3=$(lscpu 2>/dev/null | grep "L3 cache" | sed 's/.*: *//')
CPU_FLAGS=$(lscpu 2>/dev/null | grep "Flags" | sed 's/.*: *//')
CPU_VIRT=$(lscpu 2>/dev/null | grep "Virtualization" | sed 's/.*: *//')
CPU_BYTEORDER=$(lscpu 2>/dev/null | grep "Byte Order" | sed 's/.*: *//')
kv "Model" "$CPU_MODEL"
kv "Sockets / Cores / Threads" "${CPU_SOCKETS:-1} / ${CPU_CORES_PER:-?} / ${CPU_THREADS}"
kv "Frequency" "${CPU_MIN} — ${CPU_MAX}"
kv "Cache L1d/L1i" "${CPU_CACHE_L1D} / ${CPU_CACHE_L1I}"
kv "Cache L2" "$CPU_CACHE_L2"
kv "Cache L3" "$CPU_CACHE_L3"
[ -n "$CPU_VIRT" ] && kv "Virtualization" "$CPU_VIRT"
kv "Byte order" "$CPU_BYTEORDER"
# Current frequency per core
sub "Current Core Frequencies"
if [ -d /sys/devices/system/cpu/cpu0/cpufreq ]; then
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq; do
[ -f "$cpu" ] || continue
core=$(echo "$cpu" | grep -oP 'cpu\d+')
freq=$(cat "$cpu")
governor=$(cat "$(dirname "$cpu")/scaling_governor" 2>/dev/null)
printf -v line " %-8s %4d MHz [%s]" "$core" "$((freq / 1000))" "$governor"
emit "$line"
done
else
emit " [cpufreq data not available]"
fi
# CPU load
sub "CPU Load"
kv "Load average" "$(cat /proc/loadavg)"
if [ "$COMPACT" = false ]; then
sub "Key CPU Flags"
# Extract notable flags
NOTABLE_FLAGS=""
for flag in avx avx2 avx512f sse4_1 sse4_2 aes vmx svm fma f16c; do
echo "$CPU_FLAGS" | grep -qw "$flag" && NOTABLE_FLAGS+="$flag "
done
kv "Notable flags" "${NOTABLE_FLAGS:-none detected}"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run mem; then
section "MEMORY"
free -h | while IFS= read -r line; do emit " $line"; done
emit ""
if [ "$COMPACT" = false ]; then
sub "Memory Details"
if command -v dmidecode &>/dev/null && [ "$(id -u)" -eq 0 ]; then
dmidecode -t memory 2>/dev/null | grep -E "Size|Type:|Speed:|Manufacturer|Locator:" | head -20 | while IFS= read -r line; do emit " $line"; done
else
# Parse from /proc
kv "MemTotal" "$(grep MemTotal /proc/meminfo | awk '{print $2, $3}')"
kv "MemAvailable" "$(grep MemAvailable /proc/meminfo | awk '{print $2, $3}')"
kv "SwapTotal" "$(grep SwapTotal /proc/meminfo | awk '{print $2, $3}')"
kv "SwapFree" "$(grep SwapFree /proc/meminfo | awk '{print $2, $3}')"
kv "Hugepages Total" "$(grep HugePages_Total /proc/meminfo | awk '{print $2}')"
kv "Dirty" "$(grep "^Dirty:" /proc/meminfo | awk '{print $2, $3}')"
kv "Shmem" "$(grep "^Shmem:" /proc/meminfo | awk '{print $2, $3}')"
fi
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run gpu; then
section "GPU"
# NVIDIA
if command -v nvidia-smi &>/dev/null; then
sub "NVIDIA GPU"
nvidia-smi --query-gpu=name,driver_version,pci.bus_id,memory.total,memory.free,memory.used,temperature.gpu,utilization.gpu,utilization.memory,power.draw,power.limit,clocks.gr,clocks.mem,compute_mode --format=csv,noheader 2>/dev/null | while IFS=',' read -r name driver pci memtot memfree memused temp gutil mutil pdraw plimit cgr cmem cmode; do
kv "Name" "$(echo $name | xargs)"
kv "Driver" "$(echo $driver | xargs)"
kv "PCI Bus" "$(echo $pci | xargs)"
kv "VRAM Total" "$(echo $memtot | xargs)"
kv "VRAM Free" "$(echo $memfree | xargs)"
kv "VRAM Used" "$(echo $memused | xargs)"
kv "Temperature" "$(echo $temp | xargs)C"
kv "GPU Utilization" "$(echo $gutil | xargs)"
kv "Mem Utilization" "$(echo $mutil | xargs)"
kv "Power Draw / Limit" "$(echo $pdraw | xargs) / $(echo $plimit | xargs)"
kv "Clocks (GPU/Mem)" "$(echo $cgr | xargs) / $(echo $cmem | xargs)"
kv "Compute Mode" "$(echo $cmode | xargs)"
done
CUDA_RT=$(nvidia-smi 2>/dev/null | grep "CUDA Version" | awk '{print $9}')
[ -n "$CUDA_RT" ] && kv "CUDA (driver)" "$CUDA_RT"
if [ "$COMPACT" = false ]; then
sub "NVIDIA Processes"
PROCS=$(nvidia-smi --query-compute-apps=pid,name,used_memory --format=csv,noheader 2>/dev/null)
if [ -n "$PROCS" ]; then
echo "$PROCS" | while IFS=',' read -r pid name mem; do
kv "PID $(echo $pid | xargs)" "$(echo $name | xargs) ($(echo $mem | xargs))"
done
else
emit " No GPU processes running"
fi
fi
else
# Check for GPU hardware without drivers
GPU_HW=$(lspci 2>/dev/null | grep -iE "vga|3d|display" | head -5)
if [ -n "$GPU_HW" ]; then
sub "GPU Hardware (no nvidia-smi)"
echo "$GPU_HW" | while IFS= read -r line; do emit " $line"; done
else
emit " No dedicated GPU detected"
fi
fi
# Check for AMD ROCm
if command -v rocm-smi &>/dev/null; then
sub "AMD ROCm GPU"
rocm-smi 2>/dev/null | head -20 | while IFS= read -r line; do emit " $line"; done
fi
# Check for Intel GPU
if [ -d /sys/class/drm/card0 ] && [ ! -f /proc/driver/nvidia/version ]; then
sub "Integrated GPU"
for card in /sys/class/drm/card*/; do
if [ -f "${card}device/vendor" ]; then
vendor=$(cat "${card}device/vendor" 2>/dev/null)
device=$(cat "${card}device/device" 2>/dev/null)
kv "$(basename $card)" "vendor=$vendor device=$device"
fi
done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run disk; then
section "STORAGE"
sub "Filesystems"
df -hT 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Block Devices"
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,MODEL,ROTA,RQ-SIZE 2>/dev/null | while IFS= read -r line; do emit " $line"; done
if [ "$COMPACT" = false ]; then
sub "Disk I/O Stats"
if [ -f /proc/diskstats ]; then
iostat -dx 1 1 2>/dev/null | tail -n +4 | while IFS= read -r line; do emit " $line"; done
fi
sub "Mount Options"
mount | grep -E "^/dev" | while IFS= read -r line; do emit " $line"; done
# SMART status for NVMe
if command -v nvme &>/dev/null; then
sub "NVMe Health"
for dev in /dev/nvme?; do
[ -b "$dev" ] || continue
emit " Device: $dev"
nvme smart-log "$dev" 2>/dev/null | grep -E "temperature|percentage_used|available_spare|data_units" | while IFS= read -r line; do emit " $line"; done
done
elif command -v smartctl &>/dev/null; then
sub "SMART Status"
for dev in /dev/sd? /dev/nvme?n?; do
[ -b "$dev" ] || continue
SMART=$(sudo smartctl -H "$dev" 2>/dev/null | grep "SMART overall")
[ -n "$SMART" ] && kv "$dev" "$SMART"
done
fi
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run net; then
section "NETWORK"
sub "Interfaces"
ip -brief addr 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Default Route"
ip route show default 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "DNS"
if [ -f /etc/resolv.conf ]; then
grep -E "^nameserver|^search" /etc/resolv.conf | while IFS= read -r line; do emit " $line"; done
fi
# Wireless info
if command -v iwconfig &>/dev/null; then
sub "Wireless"
iwconfig 2>/dev/null | grep -v "no wireless" | grep -v "^$" | head -10 | while IFS= read -r line; do emit " $line"; done
fi
sub "Listening Ports"
ss -tlnp 2>/dev/null | while IFS= read -r line; do emit " $line"; done
if [ "$COMPACT" = false ]; then
sub "Established Connections"
ss -tnp state established 2>/dev/null | head -20 | while IFS= read -r line; do emit " $line"; done
sub "Network Stats"
for iface in $(ip -brief link 2>/dev/null | awk '{print $1}' | grep -v lo); do
RX=$(cat /sys/class/net/$iface/statistics/rx_bytes 2>/dev/null || echo 0)
TX=$(cat /sys/class/net/$iface/statistics/tx_bytes 2>/dev/null || echo 0)
RX_H=$(numfmt --to=iec $RX 2>/dev/null || echo "${RX}B")
TX_H=$(numfmt --to=iec $TX 2>/dev/null || echo "${TX}B")
kv "$iface" "RX: $RX_H TX: $TX_H"
done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run thermal; then
section "THERMALS"
for zone in /sys/class/thermal/thermal_zone*/; do
[ -d "$zone" ] || continue
name=$(cat "${zone}type" 2>/dev/null || echo "unknown")
temp=$(($(cat "${zone}temp" 2>/dev/null || echo 0) / 1000))
mode=$(cat "${zone}mode" 2>/dev/null || echo "")
policy=$(cat "${zone}policy" 2>/dev/null || echo "")
kv "$name" "${temp}C${mode:+ [$mode]}${policy:+ policy=$policy}"
done
if command -v sensors &>/dev/null && [ "$COMPACT" = false ]; then
sub "lm-sensors"
sensors 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
# Fan speed
for fan in /sys/class/hwmon/hwmon*/fan*_input; do
[ -f "$fan" ] || continue
speed=$(cat "$fan" 2>/dev/null || echo 0)
label=$(cat "$(dirname "$fan")/$(basename "$fan" _input)_label" 2>/dev/null || basename "$fan")
[ "$speed" -gt 0 ] && kv "$label" "${speed} RPM"
done
fi
# ═══════════════════════════════════════════════════════════════
if should_run kernel; then
section "KERNEL & OS"
kv "OS" "$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2)"
kv "Kernel" "$(uname -r)"
kv "Kernel version" "$(uname -v)"
kv "Arch" "$(uname -m)"
# Key kernel params
if [ "$COMPACT" = false ]; then
sub "Key sysctl"
for param in vm.swappiness vm.dirty_ratio net.core.somaxconn net.ipv4.ip_forward kernel.pid_max fs.file-max fs.inotify.max_user_watches; do
val=$(sysctl -n "$param" 2>/dev/null)
[ -n "$val" ] && kv "$param" "$val"
done
sub "Kernel Modules (GPU/Net related)"
lsmod 2>/dev/null | grep -iE "nvidia|nouveau|amd|iwl|e1000|r8169|bluetooth|snd" | while IFS= read -r line; do emit " $line"; done
fi
# Bootloader
if [ -d /boot/efi ]; then
kv "Boot mode" "UEFI"
elif [ -d /boot/grub ]; then
kv "Boot mode" "BIOS/Legacy"
fi
# Init system
kv "Init" "$(ps -p 1 -o comm= 2>/dev/null)"
# SELinux / AppArmor
if command -v getenforce &>/dev/null; then
kv "SELinux" "$(getenforce 2>/dev/null)"
elif command -v aa-status &>/dev/null; then
PROFILES=$(sudo aa-status 2>/dev/null | grep "profiles are loaded" | head -1)
kv "AppArmor" "${PROFILES:-installed}"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run users; then
section "USERS & GROUPS"
sub "Human Users (uid >= 1000)"
awk -F: '$3 >= 1000 && $3 < 65534 {printf " %-16s uid=%-6s gid=%-6s shell=%s home=%s\n", $1, $3, $4, $7, $6}' /etc/passwd
sub "Sudoers"
getent group sudo 2>/dev/null | awk -F: '{print " " $4}'
getent group wheel 2>/dev/null | awk -F: '{print " " $4}'
sub "Currently Logged In"
who 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "User Systemd Services"
systemctl --user list-units --type=service --state=active 2>/dev/null | grep -v "^$" | head -15 | while IFS= read -r line; do emit " $line"; done
fi
# ═══════════════════════════════════════════════════════════════
if should_run services; then
section "SERVICES"
sub "Active Services"
systemctl list-units --type=service --state=active --no-pager --no-legend 2>/dev/null | awk '{printf " %-40s %s\n", $1, $4}' | head -50
if [ "$COMPACT" = false ]; then
sub "Failed Services"
FAILED=$(systemctl list-units --type=service --state=failed --no-pager --no-legend 2>/dev/null)
if [ -n "$FAILED" ]; then
echo "$FAILED" | while IFS= read -r line; do emit " $line"; done
else
emit " None"
fi
sub "Enabled Services"
systemctl list-unit-files --type=service --state=enabled --no-pager --no-legend 2>/dev/null | awk '{printf " %-40s %s\n", $1, $2}' | head -40
sub "Timers"
systemctl list-timers --no-pager --no-legend 2>/dev/null | head -15 | while IFS= read -r line; do emit " $line"; done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run firewall; then
section "FIREWALL"
if command -v ufw &>/dev/null; then
sub "UFW"
sudo -n ufw status verbose 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
if command -v iptables &>/dev/null && [ "$COMPACT" = false ]; then
sub "iptables (filter)"
sudo -n iptables -L -n --line-numbers 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
if command -v nft &>/dev/null && [ "$COMPACT" = false ]; then
sub "nftables"
sudo -n nft list ruleset 2>/dev/null | head -40 | while IFS= read -r line; do emit " $line"; done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run pkg; then
section "PACKAGE MANAGEMENT"
if command -v apt &>/dev/null; then
TOTAL=$(dpkg -l 2>/dev/null | grep "^ii" | wc -l)
kv "dpkg packages" "$TOTAL installed"
kv "apt sources" "$(grep -r "^deb " /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null | wc -l) repositories"
UPGRADEABLE=$(apt list --upgradeable 2>/dev/null | grep -c "upgradable")
kv "Upgradeable" "$UPGRADEABLE packages"
if [ "$COMPACT" = false ]; then
sub "Recent Installs (last 10)"
grep " install " /var/log/dpkg.log 2>/dev/null | tail -10 | awk '{print " " $1, $2, $4}' 2>/dev/null
fi
fi
if command -v snap &>/dev/null; then
sub "Snaps"
snap list 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
if command -v flatpak &>/dev/null; then
sub "Flatpaks"
flatpak list --columns=name,version 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run dev; then
section "DEVELOPMENT TOOLS"
for tool in gcc g++ clang make cmake gdb git svn hg; do
if command -v "$tool" &>/dev/null; then
ver=$("$tool" --version 2>&1 | head -1)
kv "$tool" "$ver"
fi
done
# Interpreters
for tool in python3 python ruby perl lua java javac go; do
if command -v "$tool" &>/dev/null; then
ver=$("$tool" --version 2>&1 | head -1)
kv "$tool" "$ver"
fi
done
# Shells
sub "Shells"
cat /etc/shells 2>/dev/null | grep -v "^#" | grep -v "^$" | while IFS= read -r line; do emit " $line"; done
kv "Default shell" "$SHELL"
fi
# ═══════════════════════════════════════════════════════════════
if should_run python; then
section "PYTHON"
if command -v python3 &>/dev/null; then
kv "python3" "$(python3 --version 2>&1)"
kv "Location" "$(which python3)"
kv "pip" "$(pip3 --version 2>/dev/null || echo 'not installed')"
if [ "$COMPACT" = false ]; then
sub "System Python Packages"
pip3 list 2>/dev/null | head -30 | while IFS= read -r line; do emit " $line"; done
TOTAL_PIP=$(pip3 list 2>/dev/null | tail -n +3 | wc -l)
[ "$TOTAL_PIP" -gt 30 ] && emit " ... and $((TOTAL_PIP - 28)) more"
fi
fi
# Virtual envs
sub "Virtual Environments"
# Check common locations
for vdir in ~/.virtualenvs /opt/venvs; do
if [ -d "$vdir" ]; then
for env in "$vdir"/*/; do
[ -f "${env}bin/python" ] || continue
ver=$("${env}bin/python" --version 2>&1)
kv "$(basename $env)" "$ver ($env)"
done
fi
done
fi
# ═══════════════════════════════════════════════════════════════
if should_run conda; then
section "CONDA ENVIRONMENTS"
# Find conda
CONDA_SH=""
for try in "$HOME/miniforge3" "$HOME/miniconda3" "$HOME/anaconda3" /opt/conda; do
[ -f "$try/etc/profile.d/conda.sh" ] && CONDA_SH="$try/etc/profile.d/conda.sh" && break
done
if [ -n "$CONDA_SH" ]; then
source "$CONDA_SH"
kv "Conda" "$(conda --version 2>&1)"
kv "Location" "$(dirname $(dirname $CONDA_SH))"
kv "Active env" "${CONDA_DEFAULT_ENV:-none}"
emit ""
conda env list 2>/dev/null | grep -E "^\w" | grep -v "^#" | while read -r envname envpath; do
[ "$envname" = "base" ] && [ "$COMPACT" = true ] && continue
PYVER=$("${envpath}/bin/python" --version 2>/dev/null || echo "?")
ENVSIZE=$(du -sh "$envpath" 2>/dev/null | awk '{print $1}')
PKGCOUNT=$("${envpath}/bin/pip" list 2>/dev/null | tail -n +3 | wc -l)
emit " ▸ ${envname} (${PYVER}, ${ENVSIZE}, ${PKGCOUNT} pip packages)"
if [ "$COMPACT" = false ]; then
# Show all pip packages
"${envpath}/bin/pip" list --format=columns 2>/dev/null | tail -n +3 | while read -r pkg ver rest; do
emit " ${pkg} ${ver}"
done
emit ""
else
# Show key packages only
for pkg in torch tensorflow numpy pandas jupyter jupyterlab langchain openai anthropic faster-whisper flask fastapi; do
ver=$("${envpath}/bin/pip" show "$pkg" 2>/dev/null | grep "^Version:" | awk '{print $2}')
[ -n "$ver" ] && emit " ${pkg} ${ver}"
done
fi
# Check CUDA availability if torch is present
if "${envpath}/bin/pip" show torch &>/dev/null 2>&1; then
CUDA=$("${envpath}/bin/python" -c "import torch; print('CUDA available' if torch.cuda.is_available() else 'CPU only')" 2>/dev/null)
[ -n "$CUDA" ] && emit " [PyTorch: ${CUDA}]"
fi
emit ""
done
# Jupyter kernels
sub "Jupyter Kernels"
KERNEL_DIR="$HOME/.local/share/jupyter/kernels"
if [ -d "$KERNEL_DIR" ]; then
for kdir in "$KERNEL_DIR"/*/; do
[ -f "${kdir}kernel.json" ] || continue
kname=$(basename "$kdir")
kdisp=$(python3 -c "import json; print(json.load(open('${kdir}kernel.json'))['display_name'])" 2>/dev/null || echo "$kname")
kpy=$(python3 -c "import json; print(json.load(open('${kdir}kernel.json'))['argv'][0])" 2>/dev/null || echo "?")
kv "$kdisp" "$kpy"
done
else
emit " No user kernels"
fi
else
emit " Conda not found"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run node; then
section "NODE.JS"
if command -v node &>/dev/null; then
kv "node" "$(node --version)"
kv "npm" "$(npm --version 2>/dev/null)"
kv "Location" "$(which node)"
if command -v npx &>/dev/null; then kv "npx" "$(npx --version 2>/dev/null)"; fi
if command -v yarn &>/dev/null; then kv "yarn" "$(yarn --version 2>/dev/null)"; fi
if command -v pnpm &>/dev/null; then kv "pnpm" "$(pnpm --version 2>/dev/null)"; fi
if command -v bun &>/dev/null; then kv "bun" "$(bun --version 2>/dev/null)"; fi
sub "Global npm Packages"
npm list -g --depth=0 2>/dev/null | tail -n +2 | while IFS= read -r line; do emit " $line"; done
else
emit " Node.js not installed"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run rust; then
section "RUST"
if command -v rustc &>/dev/null; then
kv "rustc" "$(rustc --version)"
kv "cargo" "$(cargo --version 2>/dev/null)"
kv "rustup" "$(rustup --version 2>/dev/null | head -1)"
kv "Toolchain" "$(rustup show active-toolchain 2>/dev/null)"
if [ "$COMPACT" = false ]; then
sub "Installed Targets"
rustup target list --installed 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Cargo Binaries"
ls "$HOME/.cargo/bin/" 2>/dev/null | grep -v "^cargo" | grep -v "^rust" | while IFS= read -r line; do emit " $line"; done
fi
elif [ -d "$HOME/.cargo" ]; then
emit " Rust directory exists but rustc not in PATH"
else
emit " Rust not installed"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run docker; then
section "DOCKER"
if command -v docker &>/dev/null; then
kv "Docker" "$(docker --version)"
kv "Compose" "$(docker compose version 2>/dev/null || echo 'not available')"
# Docker info (might need sudo)
DINFO=$(docker info 2>/dev/null)
if [ -n "$DINFO" ]; then
kv "Storage driver" "$(echo "$DINFO" | grep "Storage Driver" | awk '{print $3}')"
kv "Docker root" "$(echo "$DINFO" | grep "Docker Root" | awk '{print $NF}')"
kv "Containers" "$(echo "$DINFO" | grep "Containers:" | awk '{print $2}')"
kv "Images" "$(echo "$DINFO" | grep "Images:" | awk '{print $2}')"
# NVIDIA runtime?
echo "$DINFO" | grep -q nvidia && kv "NVIDIA runtime" "available"
fi
sub "Running Containers"
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null | while IFS= read -r line; do emit " $line"; done
if [ "$COMPACT" = false ]; then
sub "All Containers"
docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Size}}" 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Images"
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Docker Networks"
docker network ls 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Volumes"
docker volume ls 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
else
emit " Docker not installed"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run env; then
section "ENVIRONMENT VARIABLES"
sub "Key Variables"
for var in HOME USER SHELL PATH EDITOR DISPLAY WAYLAND_DISPLAY XDG_SESSION_TYPE XDG_CURRENT_DESKTOP LANG LC_ALL TERM SSH_CONNECTION VIRTUAL_ENV CONDA_DEFAULT_ENV CUDA_VISIBLE_DEVICES OLLAMA_HOST; do
val="${!var:-}"
[ -n "$val" ] && kv "$var" "$val"
done
sub "PATH Entries"
echo "$PATH" | tr ':' '\n' | while IFS= read -r p; do
if [ -d "$p" ]; then
count=$(ls "$p" 2>/dev/null | wc -l)
emit " $p ($count entries)"
else
emit " $p [MISSING]"
fi
done
fi
# ═══════════════════════════════════════════════════════════════
if should_run cron; then
section "SCHEDULED TASKS"
sub "User Crontab"
crontab -l 2>/dev/null | grep -v "^#" | grep -v "^$" | while IFS= read -r line; do emit " $line"; done
[ -z "$(crontab -l 2>/dev/null | grep -v '^#' | grep -v '^$')" ] && emit " [empty]"
if [ "$COMPACT" = false ]; then
sub "System Crontabs"
for f in /etc/crontab /etc/cron.d/*; do
[ -f "$f" ] || continue
ENTRIES=$(grep -v "^#" "$f" | grep -v "^$" | grep -v "^SHELL" | grep -v "^PATH" | grep -v "^MAILTO")
if [ -n "$ENTRIES" ]; then
emit " [$f]"
echo "$ENTRIES" | while IFS= read -r line; do emit " $line"; done
fi
done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run dirs; then
section "KEY DIRECTORIES"
for dir in /home/*/ /opt/ /srv/ /var/www/ /var/lib/docker/ /tmp/; do
[ -d "$dir" ] || continue
size=$(du -sh "$dir" 2>/dev/null | awk '{print $1}')
count=$(find "$dir" -maxdepth 1 -mindepth 1 2>/dev/null | wc -l)
kv "$dir" "${size} (${count} items)"
done
# Home directory structure (2 levels)
sub "Home Directory"
if command -v tree &>/dev/null; then
tree -L 2 -d --noreport "$HOME" 2>/dev/null | head -40 | while IFS= read -r line; do emit " $line"; done
else
find "$HOME" -maxdepth 2 -type d 2>/dev/null | head -40 | while IFS= read -r line; do emit " $line"; done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run usb; then
section "USB DEVICES"
if command -v lsusb &>/dev/null; then
lsusb 2>/dev/null | while IFS= read -r line; do emit " $line"; done
else
emit " lsusb not available"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run pci; then
section "PCI DEVICES (key)"
if command -v lspci &>/dev/null; then
lspci 2>/dev/null | grep -iE "vga|audio|network|ethernet|wifi|usb|nvme|sata|bridge" | while IFS= read -r line; do emit " $line"; done
else
emit " lspci not available"
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run audio; then
section "AUDIO"
if command -v pactl &>/dev/null; then
sub "PulseAudio/PipeWire Sinks"
pactl list sinks short 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Sources"
pactl list sources short 2>/dev/null | while IFS= read -r line; do emit " $line"; done
elif command -v aplay &>/dev/null; then
sub "ALSA Devices"
aplay -l 2>/dev/null | while IFS= read -r line; do emit " $line"; done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run logs; then
section "RECENT SYSTEM EVENTS"
sub "Last 15 Journal Entries (priority warning+)"
journalctl -p warning --no-pager -n 15 2>/dev/null | while IFS= read -r line; do emit " $line"; done
sub "Last 5 Logins"
last -5 2>/dev/null | head -6 | while IFS= read -r line; do emit " $line"; done
if [ "$COMPACT" = false ]; then
sub "Auth Failures (last 10)"
journalctl _COMM=sshd --no-pager -n 20 2>/dev/null | grep -i "fail\|invalid\|refused" | tail -10 | while IFS= read -r line; do emit " $line"; done
fi
fi
# ═══════════════════════════════════════════════════════════════
if should_run perf; then
section "PERFORMANCE SNAPSHOT"
sub "Top 10 Processes by CPU"
ps aux --sort=-%cpu | head -11 | while IFS= read -r line; do emit " $line"; done
sub "Top 10 Processes by Memory"
ps aux --sort=-%mem | head -11 | while IFS= read -r line; do emit " $line"; done
sub "Open File Descriptors"
kv "System total" "$(cat /proc/sys/fs/file-nr | awk '{print $1}') / $(cat /proc/sys/fs/file-nr | awk '{print $3}') max"
fi
# ═══════════════════════════════════════════════════════════════
emit ""
emit "$DIVIDER"
emit " END OF PROFILE — $(hostname) — $(date '+%Y-%m-%d %H:%M:%S %Z')"
emit "$DIVIDER"
emit ""
# Save to file if requested
if [ "$SAVE" = true ]; then
OUTFILE="$HOME/sysprofile-$(date +%Y%m%d-%H%M%S).txt"
echo "$OUTPUT" > "$OUTFILE"
echo "Saved to: $OUTFILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment