On macOS, we usually rely on tools like iStat Menus or Stats for system monitoring. But as a developer, I want a lighter, hardcore, entirely controllable solution:

  • No Electron: Avoid bloated background processes.
  • No Unknowns: Need low-level values directly (e.g., SSD 0E fatal errors).
  • Fully Automated: Auto-track external drive hot-plugs WITHOUT manual config edits.
  • M3-native: Bypass Apple Silicon M-chip barriers hiding CPU thermals.

After some trial and error, I wrote an All-in-One Shell script aggregating CPU thermal/pressures, SSD health metrics (covering 0E checks), external drive tracking coordinates, and deep battery forensics.

Below is the implementation plan.

🛠️ Prerequisites

We leverage a few lightweight command-line utilities to fetch low-level values.

1. Install Dependencies

Open your terminal and install via Homebrew:

1
2
3
4
5
# Install smartmon tools (for reading SSD SMART info)
brew install smartmontools

# Install terminal-notifier (for sending macOS native notifications)
brew install terminal-notifier

2. Configure Sudo Rules

Because executing smartctl and powermetrics demands root nodes, setting up sudo passwordless lists enforces silent background operations.

Run sudo visudo and append the following lines to the end of the file (replace your_username with your actual username):

1
your_username ALL=(ALL) NOPASSWD: /opt/homebrew/bin/smartctl, /usr/bin/powermetrics

🔓 Bypassing M-Chip Barriers: Custom CPU Temp Engine

On M-chips, generic powermetrics bypasses core thermal printouts. We utilize C scripts binding Apple’s private HID interfaces.

1. Create Source Code get_temp.c

Create a new file get_temp.c and insert the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>

// Declare Apple Private HID interfaces
typedef struct __IOHIDEventSystemClient * IOHIDEventSystemClientRef;
typedef struct __IOHIDServiceClient * IOHIDServiceClientRef;
typedef struct __IOHIDEvent * IOHIDEventRef;
#define kIOHIDEventTypeTemperature 15

extern IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);
extern int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client, CFDictionaryRef match);
extern CFArrayRef IOHIDEventSystemClientCopyServices(IOHIDEventSystemClientRef client);
extern CFStringRef IOHIDServiceClientCopyProperty(IOHIDServiceClientRef service, CFStringRef key);
extern IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef service, int64_t type, int32_t options, int64_t timestamp);
extern double IOHIDEventGetFloatValue(IOHIDEventRef event, int32_t field);

int main() {
    IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
    if (!system) return 1;

    int page = 0xff00; int usage = 0x0005;
    CFNumberRef pageNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
    CFNumberRef usageNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
    const void *keys[2] = { CFSTR("PrimaryUsagePage"), CFSTR("PrimaryUsage") };
    const void *values[2] = { pageNum, usageNum };
    CFDictionaryRef matchDict = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    IOHIDEventSystemClientSetMatching(system, matchDict);
    CFArrayRef services = IOHIDEventSystemClientCopyServices(system);
    if (!services) return 1;

    CFIndex count = CFArrayGetCount(services);
    double maxTemp = 0.0;
    int found = 0;

    for (CFIndex i = 0; i < count; i++) {
        IOHIDServiceClientRef service = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, i);
        CFStringRef nameRef = IOHIDServiceClientCopyProperty(service, CFSTR("Product"));
        if (!nameRef) continue;
        char name[256];
        CFStringGetCString(nameRef, name, 256, kCFStringEncodingUTF8);
        CFRelease(nameRef);

        if (strstr(name, "SOC MDI") || strstr(name, "Die") || strstr(name, "PMU tdev") || strstr(name, "Cluster")) {
            IOHIDEventRef event = IOHIDServiceClientCopyEvent(service, kIOHIDEventTypeTemperature, 0, 0);
            if (event) {
                double temp = IOHIDEventGetFloatValue(event, (kIOHIDEventTypeTemperature << 16));
                if (temp > 20.0 && temp < 120.0) {
                    if (temp > maxTemp) maxTemp = temp;
                    found = 1;
                }
                CFRelease(event);
            }
        }
    }
    if (found) printf("%.1f\n", maxTemp); else printf("0.0\n");
    return 0;
}

2. Compile & Install

Compile using the system-installed clang and relocate to system binaries:

1
2
clang -framework CoreFoundation -framework IOKit -o get_temp get_temp.c
sudo mv get_temp /usr/local/bin/get_temp

Now, running get_temp in your terminal fetches precise CPU temperatures.


📜 Ultimate Monitor Script

This is the final shape of the script. It operates silently in the background, but when executed manually, it outputs a gorgeous “System Wellness Report”.

Save codes below into ~/script/temp_monitor.sh:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/bash

# ================= Configuration =================
EXTERNAL_DRIVE_NAME="disk"  # Your external disk layout name (inside /Volumes)

THRESHOLD_CPU=85      # CPU Alert Threshold (°C)
THRESHOLD_DISK=55     # Disk Alert Threshold (°C)
THRESHOLD_BATT=40     # Battery Alert Threshold (°C)
THRESHOLD_HEALTH=90   # Disk Health Alert Threshold (%)

# Environment variables
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

# ================= 1. Fetching Baseline Data =================

# --- A. CPU ---
# Call our custom C binary
CPU_TEMP=$(/usr/local/bin/get_temp)
if [[ -n "$CPU_TEMP" && "$CPU_TEMP" != "0.0" ]]; then
    CPU_TEMP_INT=${CPU_TEMP%.*}
else
    CPU_TEMP_INT=0; CPU_TEMP="N/A"
fi
# Fetch system thermal pressure
CPU_PRESSURE=$(sudo /usr/bin/powermetrics -n 1 --samplers thermal 2>/dev/null | grep "Current pressure level" | awk '{print $4}')
if [[ -z "$CPU_PRESSURE" ]]; then CPU_PRESSURE="Unknown"; fi

# --- B. Battery (Deep Diagnostics) ---
BATT_INFO=$(ioreg -rn AppleSmartBattery)
# Temperature
RAW_BATT_TEMP=$(echo "$BATT_INFO" | grep "\"Temperature\" =" | awk '{print $3}')
if [[ -n "$RAW_BATT_TEMP" ]]; then
    if [[ "$RAW_BATT_TEMP" -gt 100 ]]; then BATT_TEMP=$(($RAW_BATT_TEMP / 100)); else BATT_TEMP=$RAW_BATT_TEMP; fi
else BATT_TEMP=0; fi
# Cycles & Capacity
BATT_CYCLES=$(echo "$BATT_INFO" | grep "\"CycleCount\" =" | awk '{print $3}')
BATT_MAX_CAP=$(echo "$BATT_INFO" | grep "\"AppleRawMaxCapacity\" =" | awk '{print $3}')
BATT_DESIGN_CAP=$(echo "$BATT_INFO" | grep "\"DesignCapacity\" =" | awk '{print $3}')
if [[ -n "$BATT_MAX_CAP" && -n "$BATT_DESIGN_CAP" && "$BATT_DESIGN_CAP" -gt 0 ]]; then
    BATT_HEALTH=$(( 100 * BATT_MAX_CAP / BATT_DESIGN_CAP ))
else BATT_HEALTH="?"; fi

# --- C. Memory ---
RAM_LEVEL=$(sysctl -n kern.memorystatus_vm_pressure_level)
case "$RAM_LEVEL" in
    1) RAM_TXT="Nominal" ;; 2) RAM_TXT="⚠️ High Pressure" ;; *) RAM_TXT="🔥 Critical" ;;
esac

# ================= 2. Report Generator Function =================
generate_disk_report() {
    local DISK_DEV=$1
    local DISK_TYPE=$2

    echo "Reading $DISK_DEV ($DISK_TYPE) ..."
    SMART_DATA=$(sudo /opt/homebrew/bin/smartctl -a $DISK_DEV 2>/dev/null)

    # Extract critical metrics
    MODEL=$(echo "$SMART_DATA" | grep "Model Number:" | awk -F: '{print $2}' | xargs)
    if [[ -z "$MODEL" ]]; then MODEL="Unknown"; fi
    
    TEMP=$(echo "$SMART_DATA" | grep -i "Temperature:" | awk '{print $2}')
    if [[ -z "$TEMP" ]]; then TEMP="0"; fi

    # Calculate Health
    USED_PCT=$(echo "$SMART_DATA" | grep "Percentage Used" | awk '{print $3}' | tr -d '%')
    if [[ -n "$USED_PCT" ]]; then HEALTH=$((100 - USED_PCT)); else HEALTH="N/A"; USED_PCT="?"; fi

    # Aggregate Statistics
    WRITTEN=$(echo "$SMART_DATA" | grep "Data Units Written" | awk -F'[][]' '{print $2}')
    HOURS=$(echo "$SMART_DATA" | grep "Power On Hours" | awk '{print $4}' | tr -d ',')
    if [[ -n "$HOURS" ]]; then DAYS=$((HOURS / 24)); TIME_TXT="${HOURS} hours (${DAYS} days)"; else TIME_TXT="N/A"; fi
    UNSAFE=$(echo "$SMART_DATA" | grep "Unsafe Shutdowns" | awk '{print $3}' | tr -d ',')
    if [[ -z "$UNSAFE" ]]; then UNSAFE="0"; fi

    # 0E Fatal Error Detection
    ERR_0E=$(echo "$SMART_DATA" | grep "Media and Data Integrity Errors" | awk '{print $NF}')
    if [[ -z "$ERR_0E" ]]; then ERR_0E="N/A"; fi

    # Echo Visualized Report
    echo "----------------------------------------"
    if [[ "$DISK_TYPE" == "Internal" ]]; then echo " 🍎 Internal SSD (macOS System)"; else echo " 💾 External Drive ($DISK_DEV)"; fi
    echo "----------------------------------------"
    echo "📦 Model Number: $MODEL"
    echo "🌡️ Temp: ${TEMP}°C"
    echo "❤️ Lifecycles health: ${HEALTH}% (Used ${USED_PCT}%)"
    echo "📝 Data Written: $WRITTEN"
    echo "⏳ Timeline Hours: $TIME_TXT"
    echo "🔌 Abnormal Shutdowns: $UNSAFE times"
    echo "✨ 0E Bad blocks: $ERR_0E (Data integrity)"
    echo ""

    # Return data to primary logic
    eval "${DISK_TYPE}_TEMP=$TEMP"
    eval "${DISK_TYPE}_0E=$ERR_0E"
    eval "${DISK_TYPE}_HEALTH=$HEALTH"
}

# ================= 3. Execution Output =================

echo ""
echo "========================================"
echo "      📟 System Wellness Report      "
echo "========================================"
echo ""

# Computational Compute
echo "🧠 Computational Compute"
echo "----------------------------------------"
echo "CPU Temp: ${CPU_TEMP}°C"
echo "CPU Pressure: ${CPU_PRESSURE}"
echo "RAM Pressure State: ${RAM_TXT}"
echo ""

# Battery Wellness
echo "🔋 Battery Wellness"
echo "----------------------------------------"
echo "🌡️ Temp: ${BATT_TEMP}°C"
echo "🔄 Cycle count: ${BATT_CYCLES} times"
echo "❤️ Lifecycles health: ${BATT_HEALTH}%"
echo "🔋 Capacity: ${BATT_MAX_CAP} mAh (Current) / ${BATT_DESIGN_CAP} mAh (Design)"
echo ""

# Disk Detection
generate_disk_report "/dev/disk0" "Internal"

# Auto-track External Drive (APFS Compatible)
MOUNT_DEV=$(df "/Volumes/$EXTERNAL_DRIVE_NAME" 2>/dev/null | awk 'NR==2 {print $1}')
if [[ -n "$MOUNT_DEV" ]]; then
    DISK_DEVICE=$(echo "$MOUNT_DEV" | sed 's/s[0-9]*$//')
    generate_disk_report "$DISK_DEVICE" "External"
else
    echo "----------------------------------------"
    echo " 💾 External Drive ($EXTERNAL_DRIVE_NAME)"
    echo "----------------------------------------"
    echo "⚠️  Status: Not Connected"
    echo ""
    External_TEMP=0; External_0E=-1; External_HEALTH="N/A"
fi

# ================= 4. Alert Logic (Notifier) =================
MSG=""
TITLE="🔥 Critical System Alert"

# 0E Error (Highest Priority)
if [[ "$Internal_0E" != "N/A" && "$Internal_0E" -gt 0 ]]; then MSG="${MSG}💥System drive 0E error (${Internal_0E})"; fi
if [[ "$External_0E" != "N/A" && "$External_0E" -ge 0 && "$External_0E" -gt 0 ]]; then
    if [[ -n "$MSG" ]]; then MSG="${MSG}, "; fi
    MSG="${MSG}💥External drive 0E error (${External_0E})"
fi

# Lifespan Alert
if [[ "$Internal_HEALTH" != "N/A" && "$Internal_HEALTH" -lt "$THRESHOLD_HEALTH" ]]; then
    if [[ -n "$MSG" ]]; then MSG="${MSG}, "; fi
    MSG="${MSG}System drive lifespan low (${Internal_HEALTH}%)"
fi

# Overheating Alert
if [[ "$External_TEMP" -ge "$THRESHOLD_DISK" && "$External_TEMP" -gt 0 ]]; then
    if [[ -n "$MSG" ]]; then MSG="${MSG}, "; fi
    MSG="${MSG}External drive hot:${External_TEMP}°C"
fi
if [[ "$CPU_TEMP_INT" -ge "$THRESHOLD_CPU" ]]; then
    if [[ -n "$MSG" ]]; then MSG="${MSG}, "; fi
    MSG="${MSG}CPU overheat:${CPU_TEMP}°C"
fi

# Send Notification
if [[ -n "$MSG" ]]; then
    terminal-notifier -message "$MSG" -title "$TITLE" -sound default -group "system_monitor"
fi

📊 Live Demonstration

Executing bash temp_monitor.sh yields the highly granules report below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
========================================
      📟 System Wellness Report      
========================================

🧠 Computational Compute
----------------------------------------
CPU Temp: 39.5°C
CPU Pressure: Nominal
RAM Pressure State: Nominal

🔋 Battery Wellness
----------------------------------------
🌡️ Temp: 31°C
🔄 Cycle count: 156 times
❤️ Lifecycles health: 98%
🔋 Capacity: 4350 mAh (Current) / 4436 mAh (Design)

----------------------------------------
 🍎 Internal SSD (macOS System)
----------------------------------------
📦 Model Number: APPLE SSD AP0512Z
🌡️ Temp: 35°C
❤️ Lifecycles health: 100% (Used 0%)
📝 Data Written: 20.5 TB
⏳ Timeline Hours: 1500 hours (62 days)
🔌 Abnormal Shutdowns: 12 times
✨ 0E Bad blocks: 0 (Data integrity)

----------------------------------------
 💾 External Drive (/dev/disk4)
----------------------------------------
📦 Model Number: WDC WDS960G2G0C
🌡️ Temp: 46°C
❤️ Lifecycles health: 98% (Used 2%)
✨ 0E Bad blocks: 0 (Data integrity)

⚙️ Automated Triggers

To enforce interval checks minute-by-minute (only triggering popups on anomalies), deploy via crontab templates.

Simple method, append inside crontab:

1
* * * * * /bin/bash /Users/your_username/script/temp_monitor.sh >/dev/null 2>&1

Now, your Mac accommodates a completely private, transparent, and hardcore health monitoring grid. As long as your notifications tray rests silent, rest assured your Mac lives healthy and well!