ShellScript: Get CPU, Memory, OS Version

Overview

This blog post covers three Bash scripts that utilize Linux commands to extract detailed system information about CPU configuration, memory usage, and operating system details. These scripts are essential tools for system administrators and developers who need to programmatically monitor and report on system resources. Each script highlights different aspects of system diagnostics using native Linux commands like lscpu, free, and lsb_release.

Explanation with Inline Comments

#!/bin/bash

# Capture the information from lscpu into variables
total_cpus=$(lscpu | grep "^CPU(s):" | awk '{print $2}')
threads_per_core=$(lscpu | grep "^Thread(s) per core:" | awk '{print $4}')
cores_per_socket=$(lscpu | grep "^Core(s) per socket:" | awk '{print $4}')
sockets=$(lscpu | grep "^Socket(s):" | awk '{print $2}')

# Calculate total physical cores
total_physical_cores=$(($cores_per_socket * $sockets))

# Display the results
echo "Total Physical Cores: $total_physical_cores"
echo "Total Sockets: $sockets"
echo "Total Logical Processors (CPU(s)): $total_cpus"

#########################################################################################################

# Get memory usage from free command in MB and strip the headers
memory_stats=$(free -m | grep Mem | awk '{print $2}')

# Read into variables
read total_mem <<< $memory_stats

# Convert MB to GB by dividing by 1024
total_mem_gb=$(echo "scale=2; $total_mem / 1024" | bc)

# Calculate the nearest power of two for common RAM sizes
rounded_mem_gb=$(awk -v mem="$total_mem_gb" 'BEGIN{
    ram_sizes[1]=8; ram_sizes[2]=16; ram_sizes[3]=24; ram_sizes[4]=32;
    ram_sizes[5]=64; ram_sizes[6]=128;

    closest=ram_sizes[1];
    for(i in ram_sizes) {
        if (abs(ram_sizes[i] - mem) < abs(closest - mem))
            closest = ram_sizes[i];
    }
    print closest;
}

function abs(x) {return ((x < 0.0) ? -x : x)}')

# Display the results
echo "Total Memory: $rounded_mem_gb GB"

#########################################################################################################

# Try to use lsb_release to get the distribution description
if command -v lsb_release &>/dev/null; then
    description=$(lsb_release -a 2>/dev/null | grep "Description")
    if [ -n "$description" ]; then
        echo "$description"
    else
        echo "lsb_release executed but didn't return Description."
    fi
else
    echo "lsb_release not available. Trying rpm..."

    # Fallback to using rpm to query centos-release package
    rpm_package=$(rpm -q centos-release)
    if [ $? -eq 0 ]; then
        echo "CentOS release from rpm: $rpm_package"
    else
        echo "Failed to query CentOS release using rpm."
    fi
fi

Gathering CPU Information

The CPU (Central Processing Unit) is the heart of your computer, responsible for executing instructions and performing calculations. With Bash scripting, we can use commands like lscpu to capture detailed CPU information.

total_cpus=$(lscpu | grep "^CPU(s):" | awk '{print $2}')
threads_per_core=$(lscpu | grep "^Thread(s) per core:" | awk '{print $4}')
cores_per_socket=$(lscpu | grep "^Core(s) per socket:" | awk '{print $4}')
sockets=$(lscpu | grep "^Socket(s):" | awk '{print $2}')

total_physical_cores=$(($cores_per_socket * $sockets))

echo "Total Physical Cores: $total_physical_cores"
echo "Total Sockets: $sockets"
echo "Total Logical Processors (CPU(s)): $total_cpus"

Analyzing Memory Usage

Memory (RAM) plays a critical role in system performance, providing temporary storage for data and instructions. Using commands like free, we can extract memory usage statistics and perform calculations to determine total memory and round it to the nearest power of two.

memory_stats=$(free -m | grep Mem | awk '{print $2}')
read total_mem <<< $memory_stats
total_mem_gb=$(echo "scale=2; $total_mem / 1024" | bc)
rounded_mem_gb=$(awk -v mem="$total_mem_gb" 'BEGIN{
    ram_sizes[1]=8; ram_sizes[2]=16; ram_sizes[3]=24; ram_sizes[4]=32;
    ram_sizes[5]=64; ram_sizes[6]=128;

    closest=ram_sizes[1];
    for(i in ram_sizes) {
        if (abs(ram_sizes[i] - mem) < abs(closest - mem))
            closest = ram_sizes[i];
    }
    print closest;
}

function abs(x) {return ((x < 0.0) ? -x : x)}')

echo "Total Memory: $rounded_mem_gb GB"

Determining Distribution Description

Knowing the Linux distribution and version is essential for compatibility and troubleshooting. We can use commands like lsb_release and rpm to query distribution information.

if command -v lsb_release &>/dev/null; then
    description=$(lsb_release -a 2>/dev/null | grep "Description")
    if [ -n "$description" ]; then
        echo "$description"
    else
        echo "lsb_release executed but didn't return Description."
    fi
else
    # Fallback to using rpm to query centos-release package
    rpm_package=$(rpm -q centos-release)
    if [ $? -eq 0 ]; then
        echo "CentOS release from rpm: $rpm_package"
    else
        echo "Failed to query CentOS release using rpm."
    fi
fi