How to Access System Information in Bash

How to Access System Information in Bash

How to Access System Information in Bash

Whenever I’m debugging a slow server, writing a health-check script, or just building a status dashboard, the first thing I reach for is a handful of Bash commands that expose everything about the system: CPU, memory, disk, network, and processes. Linux exposes almost all of this through plain text files in /proc and /sys, plus a set of standard utilities, which makes system information one of the easiest things to work with in Bash once you know where to look. This article covers exactly how I gather and use that information.

Where System Information Lives

On Linux, most system information comes from two places:

Beginner Example: Basic System Info

#!/usr/bin/env bash

echo "Hostname: $(hostname)"
echo "Kernel: $(uname -r)"
echo "OS: $(uname -o)"
echo "Architecture: $(uname -m)"
echo "Uptime: $(uptime -p)"

Example output:

Hostname: web-server-01
Kernel: 6.8.0-45-generic
OS: GNU/Linux
Architecture: x86_64
Uptime: up 3 weeks, 2 days, 4 hours

uname reads directly from kernel data structures; -r gives the kernel release, -o the operating system name, and -m the machine hardware name (architecture).

CPU Information

echo "CPU model: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d ':' -f2 | xargs)"
echo "CPU cores: $(nproc)"

To see current CPU load:

uptime

Output:

14:32:01 up 22 days,  3:14,  2 users,  load average: 0.15, 0.22, 0.31

The three numbers are the load average over the last 1, 5, and 15 minutes respectively — a widely used, quick indicator of how busy the system has been.

Memory Information

free -h

Output:

               total        used        free      shared  buff/cache   available
Mem:            15Gi       4.2Gi       6.1Gi       210Mi       5.0Gi        10Gi
Swap:          2.0Gi          0B       2.0Gi

-h prints sizes in human-readable units (GiB, MiB) instead of raw kilobytes. Internally, free is just a formatted view of /proc/meminfo, which you can also read directly:

grep -E 'MemTotal|MemFree|MemAvailable' /proc/meminfo

Disk Usage

df -h

Output:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   32G   16G  67% /

For directory-level breakdown of what’s actually consuming space:

du -sh /var/log/*

du -sh summarizes (-s) the total size of each item in human-readable form (-h), which I use constantly when hunting down what’s filling up a disk.

Network Information

ip addr show

For a quick summary of just IPv4 addresses:

ip -4 addr show | grep inet | awk '{print $2}'

To check open listening ports:

ss -tuln

Process Information

ps aux --sort=-%mem | head -10

This lists all processes (aux), sorted by memory usage descending (--sort=-%mem), and shows the top 10 — one of the most useful one-liners I run when a server feels sluggish.

Step-by-Step: Building a System Info Script

Here’s a complete script that pulls together everything above into a single readable report:

#!/usr/bin/env bash
set -euo pipefail

echo "===== System Information Report ====="
echo "Generated: $(date)"
echo ""

echo "--- Host ---"
echo "Hostname: $(hostname)"
echo "OS: $(uname -o)"
echo "Kernel: $(uname -r)"
echo "Uptime: $(uptime -p)"
echo ""

echo "--- CPU ---"
echo "Model: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d ':' -f2 | xargs)"
echo "Cores: $(nproc)"
echo "Load average: $(cut -d ' ' -f1-3 /proc/loadavg)"
echo ""

echo "--- Memory ---"
free -h
echo ""

echo "--- Disk ---"
df -h --output=source,size,used,avail,pcent,target | grep -v tmpfs
echo ""

echo "--- Top 5 Processes by Memory ---"
ps aux --sort=-%mem | head -6
echo ""

echo "--- Network Interfaces ---"
ip -4 addr show | grep inet | awk '{print $2, $NF}'

How This Works Internally

Real-World Use Case: A Health-Check Script for Monitoring

#!/usr/bin/env bash
set -euo pipefail

DISK_THRESHOLD=85
MEM_THRESHOLD=90

disk_usage=$(df / --output=pcent | tail -1 | tr -dc '0-9')
mem_usage=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')

if [ "$disk_usage" -ge "$DISK_THRESHOLD" ]; then
    echo "WARNING: Disk usage at ${disk_usage}%"
fi

if [ "$mem_usage" -ge "$MEM_THRESHOLD" ]; then
    echo "WARNING: Memory usage at ${mem_usage}%"
fi

I run this every few minutes via cron and pipe warnings into the email script covered elsewhere in this series.

Automation Example: Logging System Metrics Over Time

#!/usr/bin/env bash
set -euo pipefail

LOG_FILE="/var/log/system_metrics.csv"

if [ ! -f "$LOG_FILE" ]; then
    echo "timestamp,cpu_load,mem_used_pct,disk_used_pct" > "$LOG_FILE"
fi

timestamp=$(date +%Y-%m-%dT%H:%M:%S)
cpu_load=$(cut -d ' ' -f1 /proc/loadavg)
mem_used_pct=$(free | awk '/Mem:/ {printf "%.1f", $3/$2 * 100}')
disk_used_pct=$(df / --output=pcent | tail -1 | tr -dc '0-9.')

echo "${timestamp},${cpu_load},${mem_used_pct},${disk_used_pct}" >> "$LOG_FILE"

Run every minute via cron to build a simple CSV time series I can later graph.

Security Considerations

Optimization Tips

Troubleshooting

Common Mistakes to Avoid

FAQs

Does this approach work the same way on macOS? Partially. macOS doesn’t have /proc, so tools like sysctl, vm_stat, and top are used instead of reading /proc/cpuinfo or /proc/meminfo directly.

What’s the difference between uptime‘s load average and actual CPU usage percentage? Load average is a count of processes wanting CPU (or waiting on I/O) averaged over time, not a direct percentage of CPU utilization. A load average of 4 on a 4-core system roughly means full utilization; the same number on a 16-core system means the system is much less loaded.

How can I get information about a Docker container’s resource usage from Bash? docker stats gives a live view, or read the container’s own cgroup files under /sys/fs/cgroup/ from inside the container for programmatic access.

Is there a single command that gives an overview of everything at once? Tools like htop, glances, or neofetch provide nice interactive overviews, but for scripting purposes, combining the individual commands shown above gives you full control over formatting and automation.

Summary

Nearly everything you’d want to know about a Linux system — CPU, memory, disk, network, and processes — is available through a small set of standard commands and the /proc virtual filesystem. Once I understood that these tools are really just structured views into files the kernel maintains in real time, building health checks, monitoring scripts, and system reports in Bash became straightforward and fast, without needing any external monitoring agent for simple use cases.

References

Exit mobile version