-
-
Save bjarneo/e55b52dfabfdb6e1090cb1757d1beaba to your computer and use it in GitHub Desktop.
dmi_fetch.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# dmi_fetch.sh | |
# | |
# This script gathers system information from `dmidecode` across multiple types | |
# and presents it in a static, 2x2 'btop'-like dashboard view. | |
# | |
# It requires root privileges to run dmidecode and will prompt for them. | |
# | |
# Usage: ./dmi_fetch.sh | |
# --- Color Definitions using tput --- | |
GREEN=$(tput setaf 2) | |
YELLOW=$(tput setaf 3) | |
BLUE=$(tput setaf 4) | |
MAGENTA=$(tput setaf 5) | |
CYAN=$(tput setaf 6) | |
WHITE=$(tput setaf 7) | |
RESET=$(tput sgr0) | |
BOLD=$(tput bold) | |
RED=$(tput setaf 1) | |
# --- Box Drawing Characters --- | |
BOX_TOP_LEFT="┌" | |
BOX_TOP_RIGHT="┐" | |
BOX_BOTTOM_LEFT="└" | |
BOX_BOTTOM_RIGHT="┘" | |
BOX_HORIZONTAL="─" | |
BOX_VERTICAL="│" | |
# --- Sudo Privilege Check --- | |
# Prompt for sudo password at the beginning of the script. | |
if [[ $EUID -ne 0 ]]; then | |
echo "This script uses 'dmidecode' which requires root privileges." | |
sudo -v | |
if [ $? -ne 0 ]; then | |
echo "${RED}Failed to obtain sudo privileges. Exiting.${RESET}" | |
exit 1 | |
fi | |
echo | |
fi | |
# --- Helper Functions --- | |
# Prints the ASCII Art header. | |
function print_header() { | |
echo -e "${CYAN}${BOLD}" | |
echo '▗▄▄▄ ▗▖ ▗▗▄▄▄▗▄▄▄▗▄▄▄▗▄▄▄▗▄▄▗▖ ▗▖' | |
echo '▐▌ █ ▐▛▚▞▜▌ █ ▐▌ ▐▌ █▐▌ ▐▌ ▐▌' | |
echo '▐▌ █ ▐▌ ▐▌ █ ▐▛▀▀▐▛▀▀▘ █▐▌ ▐▛▀▜▌' | |
echo '▐▙▄▄▀ ▐▌ ▐▗▄█▄▐▌ ▐▙▄▄▖ █▝▚▄▄▐▌ ▐▌' | |
echo -e "${RESET}" | |
echo | |
} | |
# Extracts a specific value from a block of text given a key. | |
function get_value() { | |
local key="$1" | |
local data="$2" | |
echo -e "$data" | grep -m 1 "$key" | cut -d ':' -f 2- | sed 's/^[[:space:]]*//' | |
} | |
# This function generates the formatted lines for a block and stores them in a passed array reference. | |
# It also returns the calculated width of the block. | |
# Usage: generate_block_lines "Title" content_array_name output_lines_name output_width_name [fixed_width] | |
function generate_block_lines() { | |
local title=" $1 " | |
local -n content_arr=$2 | |
local -n output_lines=$3 | |
local -n output_width=$4 | |
local fixed_width=${5:-0} # Optional: a pre-determined width to enforce | |
output_lines=() | |
output_width=0 | |
local max_width=0 | |
local clean_title | |
clean_title=$(echo "$title" | sed 's/\x1b\[[0-9;]*m//g') | |
for line in "${content_arr[@]}"; do | |
local clean_line | |
clean_line=$(echo "$line" | sed 's/\x1b\[[0-9;]*m//g') | |
[[ ${#clean_line} -gt $max_width ]] && max_width=${#clean_line} | |
done | |
[[ ${#clean_title} -gt $max_width ]] && max_width=${#clean_title} | |
max_width=$((max_width + 4)) | |
# If a fixed width is provided and it's larger, use it. | |
if [[ $fixed_width -gt $max_width ]]; then | |
max_width=$fixed_width | |
fi | |
output_width=$max_width | |
local top_border="${GREEN}${BOX_TOP_LEFT}${CYAN}${BOLD}${title}${RESET}" | |
for ((i = ${#clean_title}; i < max_width - 1; i++)); do top_border+="${GREEN}${BOX_HORIZONTAL}"; done | |
top_border+="${GREEN}${BOX_TOP_RIGHT}${RESET}" | |
output_lines+=("$top_border") | |
for line in "${content_arr[@]}"; do | |
local clean_line | |
clean_line=$(echo "$line" | sed 's/\x1b\[[0-9;]*m//g') | |
local padding=$((max_width - ${#clean_line} - 2)) | |
local content_line="${GREEN}${BOX_VERTICAL}${RESET} ${line}" | |
for ((j = 0; j < padding; j++)); do content_line+=" "; done | |
content_line+="${GREEN}${BOX_VERTICAL}${RESET}" | |
output_lines+=("$content_line") | |
done | |
local bottom_border="${GREEN}${BOX_BOTTOM_LEFT}" | |
for ((i = 0; i < max_width - 1; i++)); do bottom_border+="${GREEN}${BOX_HORIZONTAL}"; done | |
bottom_border+="${GREEN}${BOX_BOTTOM_RIGHT}${RESET}" | |
output_lines+=("$bottom_border") | |
} | |
# --- Data Gathering & Processing --- | |
echo "${GREEN}Gathering system information...${RESET}" | |
SYS_INFO=$(sudo dmidecode --type system) | |
BIOS_INFO=$(sudo dmidecode --type bios) | |
CPU_INFO=$(sudo dmidecode --type processor) | |
MEM_INFO=$(sudo dmidecode --type memory) | |
CHASSIS_INFO=$(sudo dmidecode --type chassis) | |
# Clear screen for a clean dashboard display | |
clear | |
print_header | |
# --- Panel Generation --- | |
# Declare arrays and width variables for each panel | |
declare -a TOP_LEFT_LINES && declare TOP_LEFT_WIDTH | |
declare -a TOP_RIGHT_LINES && declare TOP_RIGHT_WIDTH | |
declare -a BOTTOM_LEFT_LINES && declare BOTTOM_LEFT_WIDTH | |
declare -a BOTTOM_RIGHT_LINES && declare BOTTOM_RIGHT_WIDTH | |
# Panel 1: System & BIOS | |
MANUFACTURER=$(get_value "Manufacturer:" "$SYS_INFO") | |
PRODUCT=$(get_value "Product Name:" "$SYS_INFO") | |
VERSION=$(get_value "Version:" "$SYS_INFO") | |
SERIAL=$(get_value "Serial Number:" "$SYS_INFO") | |
BIOS_VENDOR=$(get_value "Vendor:" "$BIOS_INFO") | |
BIOS_VERSION=$(get_value "Version:" "$BIOS_INFO") | |
BIOS_DATE=$(get_value "Release Date:" "$BIOS_INFO") | |
SYSTEM_BLOCK_CONTENT=( | |
"${YELLOW}Manufacturer:${WHITE} $MANUFACTURER" | |
"${YELLOW}Product:${WHITE} $PRODUCT" | |
"${YELLOW}Version:${WHITE} $VERSION" | |
"${YELLOW}Serial:${WHITE} $SERIAL" | |
"${YELLOW}BIOS Vendor:${WHITE} $BIOS_VENDOR" | |
"${YELLOW}BIOS Version:${WHITE} $BIOS_VERSION" | |
"${YELLOW}BIOS Date:${WHITE} $BIOS_DATE" | |
) | |
generate_block_lines "System & BIOS" SYSTEM_BLOCK_CONTENT TOP_LEFT_LINES TOP_LEFT_WIDTH | |
# Panel 2: Processor | |
CPU_VERSION=$(get_value "Version:" "$CPU_INFO") | |
CPU_MANUFACTURER=$(get_value "Manufacturer:" "$CPU_INFO") | |
CPU_SPEED=$(get_value "Current Speed:" "$CPU_INFO") | |
CPU_MAX_SPEED=$(get_value "Max Speed:" "$CPU_INFO") | |
CORE_COUNT=$(get_value "Core Count:" "$CPU_INFO") | |
THREAD_COUNT=$(get_value "Thread Count:" "$CPU_INFO") | |
CPU_BLOCK_CONTENT=( | |
"${YELLOW}Version:${WHITE} $CPU_VERSION" | |
"${YELLOW}Manufacturer:${WHITE} $CPU_MANUFACTURER" | |
"${YELLOW}Speed:${WHITE} $CPU_SPEED" | |
"${YELLOW}Max Speed:${WHITE} $CPU_MAX_SPEED" | |
"${YELLOW}Cores / Threads:${WHITE} $CORE_COUNT / $THREAD_COUNT" | |
) | |
generate_block_lines "Processor" CPU_BLOCK_CONTENT TOP_RIGHT_LINES TOP_RIGHT_WIDTH | |
# Panel 3: Memory | |
declare -a MEMORY_BLOCK_CONTENT | |
TOTAL_DEVICES=$(get_value "Number Of Devices:" "$MEM_INFO") | |
MEMORY_BLOCK_CONTENT+=("${YELLOW}Memory Slots:${WHITE} $TOTAL_DEVICES") | |
current_block="" | |
while read -r line; do | |
if [[ "$line" == "Handle "* ]]; then | |
if [[ -n "$current_block" && "$current_block" =~ "Memory Device" ]]; then | |
size=$(get_value "Size:" "$current_block") | |
locator=$(get_value "Locator:" "$current_block") | |
if [[ "$size" != "No Module Installed" && -n "$size" ]]; then | |
type=$(get_value "Type:" "$current_block") | |
speed=$(get_value "Speed:" "$current_block") | |
manufacturer=$(get_value "Manufacturer:" "$current_block") | |
MEMORY_BLOCK_CONTENT+=("${MAGENTA} - ${locator:-N/A}:${RESET} ${WHITE}${size:-N/A}, ${type:-N/A}, ${speed:-N/A} (${manufacturer:-N/A})") | |
elif [[ -n "$locator" ]]; then | |
MEMORY_BLOCK_CONTENT+=("${BLUE} - ${locator}:${RESET} ${WHITE}Empty") | |
fi | |
fi | |
current_block="$line\n" | |
else | |
current_block+="$line\n" | |
fi | |
done <<<"$(echo -e "$MEM_INFO\nHandle X")" | |
generate_block_lines "Memory Devices" MEMORY_BLOCK_CONTENT BOTTOM_LEFT_LINES BOTTOM_LEFT_WIDTH | |
# --- Dashboard Assembly --- | |
# This function prints two blocks side-by-side, aligning them correctly. | |
function print_row() { | |
local -n left_lines=$1 | |
local left_width=$2 | |
local -n right_lines=$3 | |
local max_height=$((${#left_lines[@]} > ${#right_lines[@]} ? ${#left_lines[@]} : ${#right_lines[@]})) | |
for ((i = 0; i < max_height; i++)); do | |
# Use parameter expansion to provide an empty string if the array element doesn't exist. | |
# This handles rows of different heights gracefully. | |
printf "%-${left_width}s %s\n" "${left_lines[i]:-}" "${right_lines[i]:-}" | |
done | |
} | |
# Determine max width for the left column to align the two rows vertically | |
LEFT_COL_WIDTH=$((TOP_LEFT_WIDTH > BOTTOM_LEFT_WIDTH ? TOP_LEFT_WIDTH : BOTTOM_LEFT_WIDTH)) | |
# Re-generate left-column panels if they are narrower than the max width for that column. | |
# This ensures the boxes in the left column have the same width. | |
if [[ $TOP_LEFT_WIDTH -lt $LEFT_COL_WIDTH ]]; then | |
generate_block_lines "System & BIOS" SYSTEM_BLOCK_CONTENT TOP_LEFT_LINES TOP_LEFT_WIDTH $LEFT_COL_WIDTH | |
fi | |
if [[ $BOTTOM_LEFT_WIDTH -lt $LEFT_COL_WIDTH ]]; then | |
generate_block_lines "Memory Devices" MEMORY_BLOCK_CONTENT BOTTOM_LEFT_LINES BOTTOM_LEFT_WIDTH $LEFT_COL_WIDTH | |
fi | |
# Print the dashboard rows | |
print_row TOP_LEFT_LINES $LEFT_COL_WIDTH TOP_RIGHT_LINES | |
echo | |
print_row BOTTOM_LEFT_LINES $LEFT_COL_WIDTH BOTTOM_RIGHT_LINES |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment