#!/bin/bash # This ist a small script which collect system information of a Linux PC and print it as json # created by matthias of angestöpselt e.V. # created at 2022-02-17 version=1.0 charity=angestoepselt os=Linux read_uname() { read -ra uname <<< "$(uname -srm)" kernel_name="${uname[0]}" kernel_version="${uname[1]}" kernel_machine="${uname[2]}" } get_memory() { memory="$(free -g | awk '/Mem:/ {printf "%i GiB", $2}')" } get_cpu() { # Get CPU name. cpu_file="/proc/cpuinfo" cpu="$(awk -F '\\s*: | @' \ '/model name|Hardware|Processor|^cpu model|chip type|^cpu type/ { cpu=$2; if ($1 == "Hardware") exit } END { print cpu }' "$cpu_file")" # Remove un-needed patterns from cpu output. cpu="${cpu//(TM)}" cpu="${cpu//(tm)}" cpu="${cpu//(R)}" cpu="${cpu//(r)}" cpu="${cpu//CPU}" cpu="${cpu//Processor}" cpu="${cpu//Dual-Core}" cpu="${cpu//Quad-Core}" cpu="${cpu//Six-Core}" cpu="${cpu//Eight-Core}" cpu="${cpu//[1-9][0-9]-Core}" cpu="${cpu//[0-9]-Core}" cpu="${cpu//, * Compute Cores}" cpu="${cpu//Core / }" cpu="${cpu//(\"AuthenticAMD\"*)}" cpu="${cpu//with Radeon * Graphics}" cpu="${cpu//, altivec supported}" cpu="${cpu//FPU*}" cpu="${cpu//Chip Revision*}" cpu="${cpu//Technologies, Inc}" cpu="${cpu//Core2/Core 2}" # Remove CPU brand from the output. cpu="${cpu/AMD}" cpu="${cpu/Intel}" cpu="${cpu/Core? Duo}" cpu="${cpu/Qualcomm}" cpu="${cpu//[[:space:]]}" } get_disk() { type -p df &>/dev/null || { err "Disk requires 'df' to function. Install 'df' to get disk info."; return; } df_version=$(df --version 2>&1) # Create an array called 'disks' where each element is a separate line from # df's output. We then unset the first element which removes the column titles. IFS=$'\n' read -d "" -ra disks <<< "$(df "${df_flags[@]}" "${disk_show[@]:-/}")" unset "disks[0]" # Stop here if 'df' fails to print disk info. [[ ${disks[*]} ]] || { err "Disk: df failed to print the disks, make sure the disk_show array is set properly." return } for disk in "${disks[@]}"; do # Create a second array and make each element split at whitespace this time. IFS=" " read -ra disk_info <<< "$disk" disk=$((disk_info[${#disk_info[@]} - 5] / 1024/ 1024))G done } get_model() { if [[ -d /system/app/ && -d /system/priv-app ]]; then model="$(getprop ro.product.brand) $(getprop ro.product.model)" elif [[ -f /sys/devices/virtual/dmi/id/board_vendor || -f /sys/devices/virtual/dmi/id/board_name ]]; then model=$(< /sys/devices/virtual/dmi/id/board_vendor) model+=" $(< /sys/devices/virtual/dmi/id/board_name)" elif [[ -f /sys/devices/virtual/dmi/id/product_name || -f /sys/devices/virtual/dmi/id/product_version ]]; then model=$(< /sys/devices/virtual/dmi/id/product_name) model+=" $(< /sys/devices/virtual/dmi/id/product_version)" elif [[ -f /sys/firmware/devicetree/base/model ]]; then model=$(< /sys/firmware/devicetree/base/model) elif [[ -f /tmp/sysinfo/model ]]; then model=$(< /tmp/sysinfo/model) fi # Remove dummy OEM info. model=${model//To be filled by O.E.M.} model=${model//To Be Filled*} model=${model//OEM*} model=${model//Not Applicable} model=${model//System Product Name} model=${model//System Version} model=${model//Undefined} model=${model//Default string} model=${model//Not Specified} model=${model//Type1ProductConfigId} model=${model//INVALID} model=${model//All Series} model=${model//�} case $model in "Standard PC"*) model="KVM/QEMU (${model})" ;; OpenBSD*) model="vmm ($model)" ;; esac } get_vendor() { sys_vendor=$(cat /sys/devices/virtual/dmi/id/sys_vendor) } get_distro() { source /etc/os-release distro="${NAME} ${VERSION_ID}" } get_serial() { [ `id -u` -eq 0 ] && serialno=$(sudo cat /sys/devices/virtual/dmi/id/product_serial) } get_category() { category=$(hostnamectl | grep Chassis | cut -c 21-) } get_odd() { [[ $(lsblk --include 11 -n) ]] && odd="1" || odd="0" } get_mac() { mac=$(ip link | sed -n "/BROADCAST.*state UP/{n;p}" | tail -1 | tr -s " " | cut -d" " -f3) } get_anydesk_id() { dpkg-query -l "anydesk" &>/dev/null && anydesk_status="TRUE" || anydesk_status="FALSE" if [ "$anydesk_status" == "TRUE" ]; then # fetching the id of anydesk consumes most of the time when calling the script. Room for improvement andydesk_id=$(/usr/bin/anydesk --get-id) fi } get_battery() { for bat in /sys/class/power_supply/*; do if [[ $bat =~ BAT ]]; then source $bat/uevent energy_full_design="$(< "${bat}/energy_full_design")" energy_full="$(< "${bat}/energy_full")" battery=`expr ${energy_full} \* 100 / ${energy_full_design}`% fi done } get_resolution() { resolution=$(xdpyinfo | awk '/dimensions/ {print $2}') } get_display() { display=`xrandr | awk '/ connected/{print sqrt( ($(NF-2)/10)^2 + ($NF/10)^2 )/2.54}' | cut -c -2 | head -n 1` } get_desktopmanager() { echo $XDG_CURRENT_DESKTOP } # fetch informations read_uname get_memory get_cpu get_disk get_model get_vendor get_distro get_serial get_category get_odd get_mac get_desktopmanager get_anydesk_id # fetch additional laptop infos if [[ $category == "laptop" ]]; then get_battery get_resolution get_display fi # print summary in json printf '{\n' printf ' %s\n' "\"Charity\": \"${charity}\"", printf ' %s\n' "\"Distro\": \"${distro}\"", printf ' %s\n' "\"Vendor\": \"${sys_vendor}\"", printf ' %s\n' "\"Model\": \"${model}\"", printf ' %s\n' "\"Serial\": \"${serialno}\"", printf ' %s\n' "\"Platform\": \"${category}\"", printf ' %s\n' "\"CPU\": \"${cpu}\"", printf ' %s\n' "\"Memory\": \"${memory}\"", printf ' %s\n' "\"HDD\": \"${disk}\"", printf ' %s\n' "\"HW_ADDRESS\": \"${mac}\"", printf ' %s\n' "\"Anydesk_ID\": \"${andydesk_id}\"", printf ' %s\n' "\"Resolution\": \"${resolution}\"", printf ' %s\n' "\"Displaysize\": \"${display}\"", printf ' %s\n' "\"Battery_life\": \"${battery}\"", printf ' %s\n' "\"Optical_Drive\": \"${odd}\"", printf ' %s\n' "\"Version\": \"${version}\"" printf '}\n'