cf-node-bootstrap/lib/skel/.bashrc.d/11-quickinfo.bashrc
2025-02-26 09:48:10 -08:00

918 lines
No EOL
28 KiB
Bash
Executable file

#!/bin/bash
###############################################################
# MOTD/Login Quick Information script #
# This script pulls information from a variety of sources #
# in a Linux system, and aggregates it into a small table #
# that is displayed upon terminal login to the system. #
# #
# Written by Alan "pyr0ball" Weinstock #
# Enhanced for multi-distro compatibility #
###############################################################
quickinfo_version=4.0.0
prbl_functons_req_ver=2.1.0
# Source PRbL Functions locally or retrieve from online
if [ ! -z $prbl_functions ] ; then
source $prbl_functions
else
if [ -f ${rundir}/functions ] ; then
source ${rundir}/functions
else
# Iterate through get commands and fall back on next if unavailable
if command -v curl >/dev/null 2>&1; then
source <(curl -ks 'https://raw.githubusercontent.com/pyr0ball/PRbL/main/functions')
elif command -v wget >/dev/null 2>&1; then
source <(wget -qO- 'https://raw.githubusercontent.com/pyr0ball/PRbL/main/functions')
elif command -v fetch >/dev/null 2>&1; then
source <(fetch -qo- 'https://raw.githubusercontent.com/pyr0ball/PRbL/main/functions')
else
echo "Error: curl, wget, and fetch commands are not available. Please install one to retrieve PRbL functions."
exit 1
fi
fi
fi
# Locate script information
scriptname="${BASH_SOURCE[0]##*/}"
rundir="${BASH_SOURCE[0]%/*}"
########################################
# Default quickinfo bashrc Preferences #
########################################
# Disable run on non-interactive sessions (set true to disable)
interactive_only=false
# Network Adapter Preferences
# set false to hide network adapters without valid IP's
show_disconnected=true
# Ignored network adapter names (regex match)
# separate adapter names with '\|' ex. "lo\|tun0"
filtered_adapters="lo"
# Disks
allowed_disk_prefixes=(
sd
md
mapper
nvme
mmcblk
root
vd # For virtual disks (KVM/Xen)
xvd # For Xen virtual disks
)
disallowed_disk_prefixes=(
boot
snap # Exclude snap mounts
loop # Exclude loop devices
)
# Settings for additional information display
show_gpu_info=true
show_container_info=true
show_service_status=true
show_security_info=true
show_smart_status=false # Requires root privileges or sudo config
show_top_processes=true
# Services to check (space separated list)
critical_services="sshd nginx apache2 mysqld mariadb docker containerd kubelet cron"
#######################################################
# Do not change these unless you know what you're doing
# convert array to grep string
for prefix in "${allowed_disk_prefixes[@]}" ; do
allowed_disk_prefixes_string+="\\|$prefix"
done
# Remove the leading '\|' from the grep string
allowed_disk_prefixes_string="${allowed_disk_prefixes_string:2}"
for prefix in "${disallowed_disk_prefixes[@]}" ; do
disallowed_disk_prefixes_string+="\\|$prefix"
done
disallowed_disk_prefixes_string="${disallowed_disk_prefixes_string:2}"
# check PRbL functions version
if command -v vercomp >/dev/null 2>&1; then
if [[ $(vercomp $functionsrev $prbl_functons_req_ver) == 2 ]] ; then
warn "PRbL functions installed are lower than recommended ($prbl_functons_req_ver)"
warn "Some features may not work as expected"
fi
fi
################################
# Enhanced OS Detection Function
################################
detect_os() {
# Initialize OS info variables
OS="Unknown"
VER="Unknown"
ID="Unknown"
# Method 1: lsb_release
if command -v lsb_release >/dev/null 2>&1; then
OS=$(lsb_release -si)
VER=$(lsb_release -sr)
ID=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
return
fi
# Method 2: /etc/os-release
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
VER=$VERSION_ID
ID=${ID:-$NAME}
ID=$(echo $ID | tr '[:upper:]' '[:lower:]')
return
fi
# Method 3: /etc/lsb-release
if [ -f /etc/lsb-release ]; then
. /etc/lsb-release
OS=$DISTRIB_ID
VER=$DISTRIB_RELEASE
ID=$(echo $DISTRIB_ID | tr '[:upper:]' '[:lower:]')
return
fi
# Method 4: /etc/{system}-release files
for release_file in /etc/*-release; do
if [ -f "$release_file" ] && [ "$release_file" != "/etc/os-release" ] && [ "$release_file" != "/etc/lsb-release" ]; then
OS=$(head -n1 "$release_file" | cut -d' ' -f1)
VER=$(head -n1 "$release_file" | grep -o -E '[0-9]+\.[0-9]+' | head -n1)
ID=$(echo $OS | tr '[:upper:]' '[:lower:]')
return
fi
done
# Method 5: Fallback to uname
OS=$(uname -s)
VER=$(uname -r)
ID=$(echo $OS | tr '[:upper:]' '[:lower:]')
}
################################
# Package Manager Detection
################################
detect_package_manager() {
package_manager="unknown"
update_cmd=""
update_check_cmd=""
if command -v apt >/dev/null 2>&1 || command -v apt-get >/dev/null 2>&1; then
package_manager="apt"
update_cmd="apt update && apt upgrade"
if [ -f /usr/lib/update-notifier/apt-check ]; then
update_check_cmd="/usr/lib/update-notifier/apt-check --human-readable"
else
update_check_cmd="apt list --upgradable 2>/dev/null | grep -c ^"
fi
elif command -v dnf >/dev/null 2>&1; then
package_manager="dnf"
update_cmd="dnf upgrade"
update_check_cmd="dnf check-update --quiet | grep -v \"^$\" | wc -l"
elif command -v yum >/dev/null 2>&1; then
package_manager="yum"
update_cmd="yum update"
update_check_cmd="yum check-update --quiet | grep -v \"^$\" | wc -l"
elif command -v pacman >/dev/null 2>&1; then
package_manager="pacman"
update_cmd="pacman -Syu"
update_check_cmd="pacman -Qu | wc -l"
elif command -v zypper >/dev/null 2>&1; then
package_manager="zypper"
update_cmd="zypper update"
update_check_cmd="zypper list-updates | grep -c \"^v \""
elif command -v apk >/dev/null 2>&1; then
package_manager="apk"
update_cmd="apk update && apk upgrade"
update_check_cmd="apk version -v | grep -c upgradable"
fi
}
################################
# Check for Updates
################################
check_for_updates() {
packages_available=0
security_updates=0
need_updates=false
case $package_manager in
apt)
if [ -f /usr/lib/update-notifier/apt-check ]; then
packages_available=$(/usr/lib/update-notifier/apt-check 2>&1 | cut -d';' -f1)
security_updates=$(/usr/lib/update-notifier/apt-check 2>&1 | cut -d';' -f2)
if [ $packages_available -gt 0 ]; then
packages="${packages_available} updates can be installed"
need_updates=true
else
packages="0 updates available"
fi
if [ $security_updates -gt 0 ]; then
supdates="${security_updates} security updates"
need_updates=true
else
supdates="0 security updates"
fi
else
# If apt-check isn't available, try an alternative method
if command -v apt >/dev/null 2>&1; then
# This method requires root/sudo, will be empty if not available
packages_available=$(apt list --upgradable 2>/dev/null | grep -c upgradable || echo "unknown")
if [[ "$packages_available" != "unknown" && $packages_available -gt 0 ]]; then
packages="${packages_available} updates can be installed"
need_updates=true
else
packages="unknown updates available"
fi
fi
fi
;;
dnf|yum)
# Check if we can run as non-root
if timeout 5 $package_manager check-update -q &>/dev/null; then
packages_available=$($update_check_cmd)
if [ $packages_available -gt 0 ]; then
packages="${packages_available} updates can be installed"
need_updates=true
else
packages="0 updates available"
fi
else
packages="Need root to check updates"
fi
;;
pacman)
if pacman -Qu &>/dev/null; then
packages_available=$(pacman -Qu | wc -l)
if [ $packages_available -gt 0 ]; then
packages="${packages_available} updates can be installed"
need_updates=true
else
packages="0 updates available"
fi
else
packages="Need to run 'pacman -Sy' to check updates"
fi
;;
zypper)
if timeout 5 zypper list-updates &>/dev/null; then
packages_available=$(zypper list-updates | grep '^v ' | wc -l)
if [ $packages_available -gt 0 ]; then
packages="${packages_available} updates can be installed"
need_updates=true
else
packages="0 updates available"
fi
else
packages="Need root to check updates"
fi
;;
apk)
if timeout 5 apk version -v &>/dev/null; then
packages_available=$(apk version -v | grep -c upgradable)
if [ $packages_available -gt 0 ]; then
packages="${packages_available} updates can be installed"
need_updates=true
else
packages="0 updates available"
fi
else
packages="Need root to check updates"
fi
;;
*)
packages="Unknown package manager"
;;
esac
# Check for release upgrade
release_upgrade=""
if [ -x /usr/lib/ubuntu-release-upgrader/release-upgrade-motd ]; then
if [ -f /var/lib/ubuntu-release-upgrader/release-upgrade-available ]; then
release_upgrade="$(cat /var/lib/ubuntu-release-upgrader/release-upgrade-available)"
need_updates=true
fi
fi
}
################################
# CPU Temperature
################################
get_cpu_temp() {
cputemp="N/A"
# Method 1: lm-sensors
if command -v sensors >/dev/null 2>&1; then
temp=$(sensors | grep -m 1 -E 'Core 0|CPU Temp|Tdie' | grep -o -E '[0-9]+\.[0-9]+' | head -n1)
if [ ! -z "$temp" ]; then
cputemp=$(printf "%.0f" $temp)
fi
fi
# Method 2: /sys/class/thermal
if [ "$cputemp" = "N/A" ] && [ -d /sys/class/thermal ]; then
for zone in /sys/class/thermal/thermal_zone*/temp; do
if [ -f "$zone" ]; then
temp=$(cat "$zone")
if [ $temp -gt 0 ]; then
# Convert millidegrees to degrees
cputemp=$(( temp / 1000 ))
break
fi
fi
done
fi
# Method 3: Raspberry Pi specific
if [ "$cputemp" = "N/A" ] && [ -f /sys/class/thermal/thermal_zone0/temp ]; then
temp=$(cat /sys/class/thermal/thermal_zone0/temp)
cputemp=$(( temp / 1000 ))
fi
# Add color warning if temperature is high
if [[ "$cputemp" != "N/A" ]]; then
if [[ "$cputemp" -gt "65" ]]; then
cputemp="${ong}${blk}${cputemp}°C${dfl}"
else
cputemp="${cputemp}°C"
fi
fi
}
################################
# GPU Information
################################
get_gpu_info() {
gpu_info="N/A"
gpu_temp="N/A"
gpu_util="N/A"
# Check for NVIDIA GPU with nvidia-smi
if command -v nvidia-smi >/dev/null 2>&1; then
gpu_info=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n1 | cut -c -30)
gpu_temp=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader | head -n1)
gpu_util=$(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader | head -n1 | cut -d' ' -f1)
# Add color to GPU temperature
if [[ "$gpu_temp" != "N/A" ]]; then
if [[ "$gpu_temp" -gt "70" ]]; then
gpu_temp="${ong}${blk}${gpu_temp}°C${dfl}"
else
gpu_temp="${gpu_temp}°C"
fi
fi
have_gpu=true
return
fi
# Check for AMD GPU with rocm-smi
if command -v rocm-smi >/dev/null 2>&1; then
gpu_info=$(rocm-smi --showproductname | grep -v "===" | head -n1 | awk '{print $2}' | cut -c -30)
gpu_temp=$(rocm-smi --showtemp | grep -v "===" | head -n1 | awk '{print $2}')
# Add color to GPU temperature
if [[ "$gpu_temp" != "N/A" ]]; then
if [[ "$gpu_temp" -gt "70" ]]; then
gpu_temp="${ong}${blk}${gpu_temp}°C${dfl}"
else
gpu_temp="${gpu_temp}°C"
fi
fi
have_gpu=true
return
fi
# Basic GPU detection through lspci
if command -v lspci >/dev/null 2>&1; then
gpu_info=$(lspci | grep -i 'vga\|3d\|display' | head -n1 | cut -d: -f3 | cut -c -30)
if [ ! -z "$gpu_info" ]; then
have_gpu=true
return
fi
fi
have_gpu=false
}
################################
# Get Container/VM Information
################################
get_container_info() {
container_type="N/A"
container_stats="N/A"
in_container=false
# Check if running in Docker
if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null; then
container_type="Docker"
in_container=true
fi
# Check if running in LXC/LXD
if grep -q lxc /proc/1/cgroup 2>/dev/null; then
container_type="LXC"
in_container=true
fi
# Check if running in Kubernetes
if [ -f /var/run/secrets/kubernetes.io/serviceaccount/namespace ]; then
container_type="Kubernetes Pod"
in_container=true
fi
# Check for systemd-nspawn
if [ -d /run/systemd/nspawn ]; then
container_type="systemd-nspawn"
in_container=true
fi
# Check for VM
if [ "$in_container" = false ]; then
if command -v systemd-detect-virt >/dev/null 2>&1; then
virt=$(systemd-detect-virt)
if [ "$virt" != "none" ]; then
container_type="VM ($virt)"
in_container=true
fi
elif [ -e /proc/cpuinfo ]; then
if grep -q "hypervisor" /proc/cpuinfo; then
container_type="VM (unknown)"
in_container=true
fi
fi
fi
# Get Docker container stats if Docker is installed
if command -v docker >/dev/null 2>&1 && [ "$in_container" = false ]; then
container_count=$(docker ps -q 2>/dev/null | wc -l || echo "0")
if [ "$container_count" -gt 0 ]; then
container_stats="$container_count running Docker containers"
have_containers=true
else
container_stats="No running containers"
have_containers=false
fi
fi
# Get LXC container stats if LXC is installed
if command -v lxc >/dev/null 2>&1 && [ "$in_container" = false ]; then
container_count=$(lxc list --format csv -c s | grep -c RUNNING 2>/dev/null || echo "0")
if [ "$container_count" -gt 0 ]; then
container_stats="$container_stats, $container_count running LXC containers"
have_containers=true
fi
fi
}
################################
# Get Service Status
################################
get_service_status() {
services_down=()
if command -v systemctl >/dev/null 2>&1; then
for service in $critical_services; do
if systemctl is-active --quiet $service 2>/dev/null; then
# Service is running, do nothing
:
elif systemctl is-enabled --quiet $service 2>/dev/null; then
# Service is enabled but not running
services_down+=("$service")
fi
done
elif command -v service >/dev/null 2>&1; then
for service in $critical_services; do
if service $service status &>/dev/null; then
# Service is running, do nothing
:
else
# Check if service exists but is not running
if [ -f "/etc/init.d/$service" ]; then
services_down+=("$service")
fi
fi
done
fi
if [ ${#services_down[@]} -gt 0 ]; then
service_status="${lrd}Services down: ${services_down[*]}${dfl}"
have_service_issues=true
else
service_status="${grn}All monitored services running${dfl}"
have_service_issues=false
fi
}
################################
# Get Security Information
################################
get_security_info() {
failed_logins=0
last_login="N/A"
ssh_sessions=0
# Get failed login attempts
if command -v journalctl >/dev/null 2>&1; then
failed_logins=$(journalctl -u sshd --since yesterday | grep -c "Failed password")
elif [ -f /var/log/auth.log ]; then
failed_logins=$(grep -c "Failed password" /var/log/auth.log)
fi
# Get last successful login
if command -v last >/dev/null 2>&1; then
last_user=$(who am i | awk '{print $1}')
if [ ! -z "$last_user" ]; then
last_login=$(last -n 2 $last_user | head -n 1 | awk '{print $4" "$5" "$6" "$7}')
fi
fi
# Get current SSH sessions
if command -v who >/dev/null 2>&1; then
ssh_sessions=$(who | grep -c "pts")
fi
# Get firewall status
if command -v ufw >/dev/null 2>&1; then
firewall_status=$(ufw status | head -n 1)
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall_status="firewalld: $(firewall-cmd --state)"
elif command -v iptables >/dev/null 2>&1; then
iptables_rules=$(iptables -L -n | grep -c "REJECT\|DROP")
if [ $iptables_rules -gt 0 ]; then
firewall_status="iptables: $iptables_rules blocking rules active"
else
firewall_status="iptables: No blocking rules found"
fi
else
firewall_status="No firewall detected"
fi
}
################################
# Get SMART Disk Status
################################
get_smart_status() {
smart_alerts=()
if command -v smartctl >/dev/null 2>&1; then
for disk in $(lsblk -d -o name | grep -E "^($allowed_disk_prefixes_string)" | grep -v -E "^($disallowed_disk_prefixes_string)"); do
# Try to run smartctl without sudo first
smart_status=$(smartctl -H /dev/$disk 2>/dev/null)
if [ $? -ne 0 ]; then
# If failed, try with sudo if available (won't work without password prompt in most cases)
if command -v sudo >/dev/null 2>&1; then
smart_status=$(sudo -n smartctl -H /dev/$disk 2>/dev/null || echo "Permission denied")
else
smart_status="Permission denied"
fi
fi
if echo "$smart_status" | grep -q "FAILED"; then
smart_alerts+=("${lrd}/dev/$disk FAILED${dfl}")
elif echo "$smart_status" | grep -q "Permission denied"; then
continue
fi
done
fi
if [ ${#smart_alerts[@]} -gt 0 ]; then
smart_status="${lrd}SMART Alerts: ${smart_alerts[*]}${dfl}"
have_smart_issues=true
else
smart_status="${grn}No SMART alerts detected${dfl}"
have_smart_issues=false
fi
}
################################
# Get Top Processes
################################
get_top_processes() {
if command -v ps >/dev/null 2>&1; then
# Get top 3 CPU processes
top_cpu=$(ps -eo pcpu,pid,user,args --sort=-pcpu | head -n 4 | tail -n 3 | awk '{printf "%-5s %-8s %-15.15s\n", $1"%", $3, $4}')
# Get top 3 memory processes
top_mem=$(ps -eo pmem,pid,user,args --sort=-pmem | head -n 4 | tail -n 3 | awk '{printf "%-5s %-8s %-15.15s\n", $1"%", $3, $4}')
fi
}
################################
# Main Logic
################################
# Run detection functions
detect_os
detect_package_manager
check_for_updates
get_cpu_temp
# Get network information
location=$(uname -a | awk '{print $2}')
image_version=$(uname -r)
software_version="$OS $VER"
mem_usage=$(free -m | grep Mem | awk '{print $3"M/"$2"M"}')
# Get swap usage
swap_usage=$(free -m | grep Swap | awk '{if ($2 > 0) print $3"M/"$2"M"; else print "None"}')
# Get number of CPUs and load averages
num_cpus=$(nproc 2>/dev/null || grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1)
load_check=$(uptime | sed -r 's|.*load average: ([\.0-9]+), ([\.0-9]+), ([\.0-9]+)|\1 \2 \3|g')
load_averages=$(echo "$load_check $num_cpus" | awk '{printf "5min: %.0f%% ", $1/$4*100} {printf "10min: %.0f%% ", $2/$4*100} {printf "15min: %.0f%%", $3/$4*100}' ORS=' ')
# Calculate CPU utilization
# Read /proc/stat file (for first datapoint)
read cpu user nice system idle iowait irq softirq steal guest < /proc/stat
# compute active and total utilizations
cpu_active_prev=$((user+system+nice+softirq+steal))
cpu_total_prev=$((user+system+nice+softirq+steal+idle+iowait))
sleep 0.3
# Read /proc/stat file (for second datapoint)
read cpu user nice system idle iowait irq softirq steal guest < /proc/stat
# compute active and total utilizations
cpu_active_cur=$((user+system+nice+softirq+steal))
cpu_total_cur=$((user+system+nice+softirq+steal+idle+iowait))
# compute CPU utilization (%)
cpu_util=$((100*( cpu_active_cur-cpu_active_prev ) / (cpu_total_cur-cpu_total_prev) ))
# Get uptime in human-readable format
if [[ "$(uptime | grep -iq day ; echo $?)" == "0" ]] ; then
# first logic gate, if the system has been online for at least a day
if [[ "$(uptime | grep -iq min ; echo $?)" == "0" ]] ; then
# nested logic gate. If the system has been online for more than a day
# but less than a day and an hour, the tokens shift and requires alternate parsing
s_uptime=$(uptime | awk '{print $3 " " $4 " " $5 " Minutes"}')
else # gate for if the system has been online longer than one day and one hour
s_uptime=$(uptime | awk '{print $3 " " $4 " " $5 " Hours"}')
fi
else # logic gate for if the system has been online less than a day but more than an hour
if [[ "$(uptime | grep -iq min ; echo $?)" == "1" ]] ; then
s_uptime=$(uptime | awk '{print $3 " Hours "}')
else
s_uptime=$(uptime | awk '{print $3 " Minutes "}')
fi
fi
# Get additional information if enabled
if [ "$show_gpu_info" = true ]; then
get_gpu_info
fi
if [ "$show_container_info" = true ]; then
get_container_info
fi
if [ "$show_service_status" = true ]; then
get_service_status
fi
if [ "$show_security_info" = true ]; then
get_security_info
fi
if [ "$show_smart_status" = true ]; then
get_smart_status
fi
if [ "$show_top_processes" = true ]; then
get_top_processes
fi
# Check for fsck message
if [ -x /usr/lib/update-notifier/update-motd-fsck-at-reboot ]; then
fsck_needed="$(exec /usr/lib/update-notifier/update-motd-fsck-at-reboot)"
fi
# Check if reboot required by updates
reboot_required=""
if [ -f /var/run/reboot-required ]; then
reboot_required=$(cat /var/run/reboot-required)
fi
# Network display and filtering
declare -a adapters=()
declare -a ips=()
declare -a macs=()
declare -a ifups=()
for device in $(ls /sys/class/net/ 2>/dev/null | grep -v "$filtered_adapters"); do
adapters+=($device)
_ip=$(ip -o -f inet addr show $device 2>/dev/null | awk '{print $4}' | cut -d/ -f 1 | head -n 1)
if valid-ip $_ip; then
ips+=("$_ip")
ifups+=("up")
else
ips+=("${red}disconnected${dfl}")
ifups+=("down")
fi
if [ -f /sys/class/net/${device}/address ]; then
macs=()
macs+=("$(cat /sys/class/net/${device}/address)")
else
macs+=("unknown")
fi
done
# Get public IP address using multiple fallbacks
get_wan_ip() {
wan_ip="Unavailable"
# Try multiple services with a timeout to avoid hanging
if command -v curl >/dev/null 2>&1; then
wan_ip=$(timeout 2 curl -s ifconfig.me 2>/dev/null || \
timeout 2 curl -s icanhazip.com 2>/dev/null || \
timeout 2 curl -s ipecho.net/plain 2>/dev/null || \
timeout 2 curl -s api.ipify.org 2>/dev/null || \
echo "Unavailable")
elif command -v wget >/dev/null 2>&1; then
wan_ip=$(timeout 2 wget -qO- ifconfig.me 2>/dev/null || \
timeout 2 wget -qO- icanhazip.com 2>/dev/null || \
timeout 2 wget -qO- ipecho.net/plain 2>/dev/null || \
timeout 2 wget -qO- api.ipify.org 2>/dev/null || \
echo "Unavailable")
elif command -v fetch >/dev/null 2>&1; then
wan_ip=$(timeout 2 fetch -qo- ifconfig.me 2>/dev/null || \
timeout 2 fetch -qo- icanhazip.com 2>/dev/null || \
timeout 2 fetch -qo- ipecho.net/plain 2>/dev/null || \
timeout 2 fetch -qo- api.ipify.org 2>/dev/null || \
echo "Unavailable")
fi
echo "$wan_ip"
}
# Run as a background process to avoid hanging the login
wan_ip=$(get_wan_ip &)
# Disk array setup
declare -a logicals=()
declare -a mounts=()
declare -a usages=()
declare -a freespaces=()
diskinfo=$(/bin/df -h | grep -E "$allowed_disk_prefixes_string" | grep -v -E "$disallowed_disk_prefixes_string")
logicals=($(echo "$diskinfo" | awk '{print $1}'))
mounts=($(echo "$diskinfo" | awk '{print $6}'))
usages=($(echo "$diskinfo" | awk '{print $5}'))
freespaces=($(echo "$diskinfo" | awk '{print $4}'))
# Add color to disk usage if more than 90%
for i in "${!usages[@]}"; do
usage="${usages[$i]}"
percentage="${usage%\%}"
if [[ "$percentage" -gt "90" ]]; then
usages[$i]="${lrd}${usage}${dfl}"
elif [[ "$percentage" -gt "75" ]]; then
usages[$i]="${ong}${usage}${dfl}"
fi
done
###############################################
# Display the formatted information
###############################################
boxtop
boxline ""
boxline "${bld}${unl}System Information:${dfl} ${grn}${unl}$location${dfl}"
boxline " ${bld}OS:${dfl} ${ong}${software_version}${dfl} | ${bld}Kernel:${dfl} ${pur}${image_version}${dfl}"
boxline " ${bld}Uptime:${dfl} ${s_uptime}"
# Container information
if [ "$show_container_info" = true ] && [[ "$in_container" = true || "$have_containers" = true ]]; then
boxline ""
boxline "${bld}${unl}Container/VM Information:${dfl}"
if [ "$in_container" = true ]; then
boxline " ${bld}Running in:${dfl} ${ylw}${container_type}${dfl}"
fi
if [ "$have_containers" = true ]; then
boxline " ${bld}Container Status:${dfl} ${container_stats}"
fi
fi
# Network information
boxline ""
boxline "${bld}${unl}Network Information:${dfl}"
# Echo out network arrays
for ((i=0; i<"${#adapters[@]}"; i++ )); do
if [[ $show_disconnected != true ]]; then
if [[ ${ifups[$i]} == up ]]; then
boxline " ${adapters[$i]}: ${cyn}${ips[$i]}${dfl} | ${blu}${macs[$i]}${dfl}"
fi
else
boxline " ${adapters[$i]}: ${cyn}${ips[$i]}${dfl} | ${blu}${macs[$i]}${dfl}"
fi
done
boxline " ${bld}WAN IP:${dfl} ${ylw}${wan_ip}${dfl}"
# System status
boxline ""
boxline "${bld}${unl}System Resources:${dfl}"
boxline " ${bld}CPU Load:${dfl} ${load_averages}"
boxline " ${bld}CPU Temp:${dfl} ${lbl}${cputemp}${dfl} | ${bld}Utilization:${dfl} ${lrd}${cpu_util}%${dfl}"
# GPU information if available
if [ "$show_gpu_info" = true ] && [ "$have_gpu" = true ]; then
boxline " ${bld}GPU:${dfl} ${ylw}${gpu_info}${dfl}"
if [ "$gpu_temp" != "N/A" ]; then
boxline " ${bld}GPU Temp:${dfl} ${lbl}${gpu_temp}${dfl} | ${bld}Utilization:${dfl} ${lrd}${gpu_util}%${dfl}"
fi
fi
# Memory usage
boxline " ${bld}Memory:${dfl} ${mem_usage} | ${bld}Swap:${dfl} ${swap_usage}"
# Storage info
boxline " ${bld}${unl}Disk Info:${dfl}"
boxline "${unl}$(printf '\t|%-4s\t%-4s\t%-4s\t%-4s\n' Usage Free Mount Volumes)${dfl}"
for ((i=0; i<"${#logicals[@]}" ; i++ )); do
boxline " $(printf '|%-4s\t%-4s\t%-4s\t%-4s\n' "${usages[$i]}" "${freespaces[$i]}" "${mounts[$i]}" "${logicals[$i]}")"
done
# SMART status if enabled and issues detected
if [ "$show_smart_status" = true ] && [ "$have_smart_issues" = true ]; then
boxline ""
boxline "${bld}${unl}Disk Health:${dfl}"
boxline " ${smart_status}"
fi
# Service status if enabled and issues detected
if [ "$show_service_status" = true ] && [ "$have_service_issues" = true ]; then
boxline ""
boxline "${bld}${unl}Service Status:${dfl}"
boxline " ${service_status}"
fi
# Security information if enabled
if [ "$show_security_info" = true ]; then
boxline ""
boxline "${bld}${unl}Security Information:${dfl}"
boxline " ${bld}Failed logins (24h):${dfl} ${failed_logins}"
boxline " ${bld}Active SSH sessions:${dfl} ${ssh_sessions}"
if [ "$last_login" != "N/A" ]; then
boxline " ${bld}Last login:${dfl} ${last_login}"
fi
boxline " ${bld}Firewall:${dfl} ${firewall_status}"
fi
# Top processes if enabled
if [ "$show_top_processes" = true ]; then
boxline ""
boxline "${bld}${unl}Top CPU Processes:${dfl}"
echo "$top_cpu" | while IFS= read -r line; do
boxline " $line"
done
boxline ""
boxline "${bld}${unl}Top Memory Processes:${dfl}"
echo "$top_mem" | while IFS= read -r line; do
boxline " $line"
done
fi
# Update information if needed
if [[ "$need_updates" == "true" ]]; then
boxline ""
boxline "${bld}${unl}Updates:${dfl}"
boxline " ${packages}"
if [ ! -z "$supdates" ]; then
boxline " ${supdates}"
fi
if [ ! -z "$release_upgrade" ]; then
boxline " ${release_upgrade}"
fi
fi
# System maintenance notifications
if [ ! -z "${fsck_needed}" ] || [ ! -z "${reboot_required}" ]; then
boxline ""
boxline "${bld}${unl}System Maintenance:${dfl}"
boxline " ${fsck_needed} ${reboot_required}"
fi
boxline ""
boxbottom