Automated Linux System Inspection Script for Comprehensive Health Checks
This article provides a Bash script that automatically gathers Linux system information—including OS details, uptime, CPU and memory usage, disk utilization with tiered alerts, network interfaces, top memory‑consuming processes, key service status, pending updates, recent error logs, load average, TCP connections, and zombie processes—and shows how to schedule it with cron for daily reporting.
1. System Information
Hostname : displays the server hostname.
Operating System : reads /etc/os-release to get the distribution name and version.
Kernel Version : outputs uname -r.
Running Environment : detects whether the host is a virtual machine (supports VMware/KVM/Xen, etc.) or a physical machine.
2. Uptime
Calculates system uptime in days and hours using /proc/uptime.
3. CPU Information
Core Count : number of logical CPUs ( nproc).
Usage : calculates current CPU usage as 100 - idle% from top output.
4. Memory Information
Total Memory : physical memory size.
Used Memory : actual used memory including cache.
Usage Percentage : automatically computed and formatted.
5. Disk Information
Excludes virtual filesystems ( tmpfs, devtmpfs, cdrom).
Checks usage of all physical mount points.
Tiered alerts: ≤80% normal, 80‑90% warning (yellow), >90% critical (red).
6. Network Information
Lists all network interface names.
Shows IPv4 addresses while excluding the loopback address (127.0.0.1).
7. Process Information
Displays the top 5 processes by RSS memory usage, showing process name, RSS size, and percentage of total memory.
8. Key Service Checks
Verifies the running status of sshd, crond, network, and firewalld, reporting each as "running" or "not running".
9. System Update Check
For Ubuntu/Debian: uses apt list --upgradable to count upgradable packages.
For CentOS/RHEL/Oracle Linux: uses dnf check-update or yum check-update depending on availability.
Reports the number of available updates or indicates an unknown package manager.
10. Error Log
Shows the most recent 5 system error log entries using journalctl -p err -n 5, including timestamps and details.
11. Additional Checks
System Load : displays average load from uptime.
TCP Connection Status : summarizes TCP connections via ss -s.
Zombie Processes : counts zombie processes; if any are found, lists them, otherwise reports none.
Script Content
#!/bin/bash
# Linux system inspection script
# Supports: CentOS 7/8, Ubuntu 18.04/20.04/22.04, Debian 9/10/11
set -e
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
REPORT_TIME=$(date +"%Y-%m-%d %H:%M:%S")
OUTPUT_FILE="/tmp/linux_check_${TIMESTAMP}.txt"
# Detect OS
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
OS_VERSION=$VERSION_ID
else
echo "Unable to detect OS version"
exit 1
fi
# Generate report
{
echo "Linux System Inspection Report"
echo "===================="
echo "Inspection Time: $REPORT_TIME"
echo ""
# System Information
echo "【System Information】"
echo "Hostname: $(hostname)"
echo "OS: $PRETTY_NAME"
echo "Kernel: $(uname -r)"
if systemd-detect-virt -q 2>/dev/null; then
echo "Environment: Virtual Machine ($(systemd-detect-virt))"
else
echo "Environment: Physical Machine"
fi
echo ""
# Uptime
echo "【Uptime】"
UPTIME_SECONDS=$(cat /proc/uptime | awk '{print $1}' | cut -d. -f1)
UPTIME_DAYS=$((UPTIME_SECONDS / 86400))
UPTIME_HOURS=$(((UPTIME_SECONDS % 86400) / 3600))
echo "Running for: ${UPTIME_DAYS} days ${UPTIME_HOURS} hours"
echo ""
# CPU Information
echo "【CPU Information】"
CPU_CORES=$(nproc)
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
echo "Cores: $CPU_CORES"
echo "Current Usage: ${CPU_USAGE}%"
echo ""
# Memory Information
echo "【Memory Information】"
MEM_TOTAL=$(free -b | grep Mem | awk '{print $2}')
MEM_USED=$(free -b | grep Mem | awk '{print $3}')
MEM_USAGE_PERCENT=$(awk "BEGIN {printf \"%.1f\", ($MEM_USED / $MEM_TOTAL) * 100}")
echo "Total: $(numfmt --to=iec $MEM_TOTAL)"
echo "Used: $(numfmt --to=iec $MEM_USED) (${MEM_USAGE_PERCENT}%)"
echo ""
# Disk Information
echo "【Disk Information】"
df -h -x tmpfs -x devtmpfs -x cdrom | tail -n +2 | while read -r filesystem size used avail use_percent mount; do
use_num=$(echo "$use_percent" | sed 's/%//')
if [ -n "$use_num" ] && [ "$use_num" -eq "$use_num" ] 2>/dev/null; then
if [ "$use_num" -gt 90 ]; then
echo "$mount: Warning (${use_percent})"
elif [ "$use_num" -gt 80 ]; then
echo "$mount: Notice (${use_percent})"
else
echo "$mount: Normal (${use_percent})"
fi
else
echo "$mount: Info (${use_percent})"
fi
done
echo ""
# Network Information
echo "【Network Information】"
ip -4 addr show | grep -E "^[0-9]+:|inet " | while read -r line; do
if echo "$line" | grep -q "^[0-9]"; then
IFACE=$(echo "$line" | awk -F: '{print $2}' | xargs)
echo "$IFACE:"
elif echo "$line" | grep -q "inet "; then
IP=$(echo "$line" | awk '{print $2}' | cut -d/ -f1)
echo " $IP"
fi
done
echo ""
# Process Information
echo "【Process Information】"
echo "Top 5 Memory Consumers (RSS):"
ps aux --sort=-rss | head -6 | tail -5 | awk '{printf " %s: %s (%.1f%%)
", $11, $6, $4}'
echo ""
# Key Services
echo "【Key Services】"
for service in sshd crond network firewalld; do
if systemctl is-active --quiet $service 2>/dev/null; then
echo "$service: Running"
else
echo "$service: Not Running"
fi
done
echo ""
# Update Check
echo "【System Updates】"
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
UPDATES=$(apt list --upgradable 2>/dev/null | grep -v "^Listing" | wc -l)
echo "Upgradable packages: $UPDATES"
elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "ol" ]; then
if command -v dnf &>/dev/null; then
UPDATES=$(dnf check-update --quiet 2>/dev/null | grep -v "^$" | wc -l)
else
UPDATES=$(yum check-update --quiet 2>/dev/null | grep -v "^$" | wc -l)
fi
echo "Upgradable packages: $UPDATES"
else
echo "Unknown package manager"
fi
echo ""
# Error Log
echo "【Error Log】"
journalctl -p err -n 5 --no-pager 2>/dev/null | while read -r line; do
echo " $line"
done
echo ""
# System Load
echo "【System Load】"
LOAD=$(uptime | awk -F'load average:' '{print $2}')
echo "Average Load: $LOAD"
echo ""
# TCP Connection Status
echo "【Connection Status】"
ss -s | grep -E "(TCP| estab| closed| syn)"
echo ""
# Zombie Processes
echo "【Zombie Processes】"
ZOMBIES=$(ps aux | awk '$8=="Z"' | wc -l)
if [ "$ZOMBIES" -gt 0 ]; then
echo "Found $ZOMBIES zombie processes"
ps aux | awk '$8=="Z"'
else
echo "No zombie processes"
fi
echo ""
echo "Report completed"
} > "$OUTPUT_FILE"
cat "$OUTPUT_FILE"
# Add load check
echo "【System Load】"
LOAD=$(uptime | awk -F'load average:' '{print $2}')
echo "Average Load: $LOAD"
# Add TCP connection status statistics
echo "【Connection Status】"
ss -s | grep -E "(TCP| estab| closed| syn)"
# Add zombie process check
echo "【Zombie Processes】"
ZOMBIES=$(ps aux | awk '$8=="Z"' | wc -l)
if [ "$ZOMBIES" -gt 0 ]; then
echo "Found $ZOMBIES zombie processes"
ps aux | awk '$8=="Z"'
else
echo "No zombie processes"
fi12. Scheduled Automatic Inspection
Set up a daily cron job to run the script and email the report:
crontab -e
# Add the following line (run at 08:00 every day and send via mail)
0 8 * * * /root/linuxcheck.sh | mail -s "Server Inspection Report-$(date +%Y%m%d)" [email protected]Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Linux Tech Enthusiast
Focused on sharing practical Linux technology content, covering Linux fundamentals, applications, tools, as well as databases, operating systems, network security, and other technical knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
