#!/bin/bash
# 先完成 sudo 认证
echo "请输入密码以开始监控..."
if ! sudo -v; then
echo "认证失败,退出监控程序"
exit 1
fi
# concise = 简洁
# aesthetic = 美观
# 显示类型
showType="aesthetic"
# 刷新频率(毫秒)
refreshRate=1000
# mW(毫瓦) 或 W(瓦)
powerUnit="W"
# 是否显示每小时耗电量:true 或 false
powerConsumptionPerHour=true
echo "开始监控 Combined Power 和 Thermal Pressure..."
echo "按 Ctrl+C 停止监控"
echo "----------------------------------------"
if [[ "$showType" == "concise" ]]; then
# 监控循环
sudo powermetrics --samplers cpu_power,thermal -i $refreshRate | grep --line-buffered -E "Combined Power|Current pressure level" | while IFS= read -r line; do
timestamp=$(date "+%H:%M:%S")
# 单位转换
if [[ "$powerUnit" == "W" ]] && [[ "$line" == *"mW"* ]]; then
line=$(echo "$line" | perl -pe 's/(\d+) mW/sprintf("%.3f W", $1\/1000)/ge')
fi
echo "[$timestamp] $line"
if [[ "$line" == *"Current pressure level"* ]]; then
echo "---"
fi
done
elif [[ "$showType" == "aesthetic" ]]; then
# 更加美观的方式
if [[ "$powerUnit" == "mW" ]]; then
echo "功耗监控 (单位: mW)"
unit_suffix=" mW"
else
echo "功耗监控 (单位: W)"
unit_suffix=" W"
fi
# 根据是否显示耗电量调整表头
if [[ "$powerConsumptionPerHour" == "true" ]]; then
echo "时间 | CPU | GPU | ANE | Combined | Thermal | powerConsumptionPerHour"
echo "-----------------------------------------------------------------------------------------"
else
echo "时间 | CPU | GPU | ANE | Combined | Thermal"
echo "---------------------------------------------------------------"
fi
sudo powermetrics --samplers cpu_power,thermal -i $refreshRate | {
# 初始化变量
cpu=""
gpu=""
ane=""
combined=""
thermal=""
power_consumption=""
while IFS= read -r line; do
# 提取各组件功耗数值
if [[ "$line" == *"CPU Power"* ]] && [[ "$line" != *"Combined"* ]]; then
cpu_value=$(echo "$line" | grep -oE '[0-9]+ mW' | head -1 | grep -oE '[0-9]+')
if [[ -n "$cpu_value" ]]; then
if [[ "$powerUnit" == "W" ]]; then
cpu_value_w=$(echo "scale=3; $cpu_value / 1000" | bc 2>/dev/null | sed 's/^\./0./' || echo "?")
cpu="${cpu_value_w}${unit_suffix}"
else
cpu="${cpu_value}${unit_suffix}"
fi
fi
elif [[ "$line" == *"GPU Power"* ]]; then
gpu_value=$(echo "$line" | grep -oE '[0-9]+ mW' | head -1 | grep -oE '[0-9]+')
if [[ -n "$gpu_value" ]]; then
if [[ "$powerUnit" == "W" ]]; then
gpu_value_w=$(echo "scale=3; $gpu_value / 1000" | bc 2>/dev/null | sed 's/^\./0./' || echo "?")
gpu="${gpu_value_w}${unit_suffix}"
else
gpu="${gpu_value}${unit_suffix}"
fi
fi
elif [[ "$line" == *"ANE Power"* ]]; then
ane_value=$(echo "$line" | grep -oE '[0-9]+ mW' | head -1 | grep -oE '[0-9]+')
if [[ -n "$ane_value" ]]; then
if [[ "$powerUnit" == "W" ]]; then
ane_value_w=$(echo "scale=3; $ane_value / 1000" | bc 2>/dev/null | sed 's/^\./0./' || echo "?")
ane="${ane_value_w}${unit_suffix}"
else
ane="${ane_value}${unit_suffix}"
fi
fi
elif [[ "$line" == *"Combined Power"* ]]; then
combined_value=$(echo "$line" | grep -oE '[0-9]+ mW' | head -1 | grep -oE '[0-9]+')
if [[ -n "$combined_value" ]]; then
if [[ "$powerUnit" == "W" ]]; then
combined_value_w=$(echo "scale=3; $combined_value / 1000" | bc 2>/dev/null | sed 's/^\./0./' || echo "?")
combined="${combined_value_w}${unit_suffix}"
else
combined="${combined_value}${unit_suffix}"
fi
# 计算每小时耗电量(始终使用 kWh)
if [[ "$powerConsumptionPerHour" == "true" ]]; then
# 直接计算 kWh:mW → W → kW → kWh/小时
power_consumption_kwh=$(echo "scale=6; $combined_value / 1000 / 1000" | bc 2>/dev/null)
if [[ -n "$power_consumption_kwh" ]]; then
# 统一使用 kWh 显示,但根据数值大小调整精度
if (( $(echo "$power_consumption_kwh < 0.0001" | bc -l 2>/dev/null) )); then
power_consumption="0.0000 kWh"
elif (( $(echo "$power_consumption_kwh < 0.001" | bc -l 2>/dev/null) )); then
power_consumption=$(echo "scale=5; $power_consumption_kwh" | bc | xargs printf "%.5f kWh\n")
elif (( $(echo "$power_consumption_kwh < 0.01" | bc -l 2>/dev/null) )); then
power_consumption=$(echo "scale=4; $power_consumption_kwh" | bc | xargs printf "%.4f kWh\n")
else
power_consumption=$(echo "scale=3; $power_consumption_kwh" | bc | xargs printf "%.3f kWh\n")
fi
else
power_consumption="N/A"
fi
fi
fi
elif [[ "$line" == *"Current pressure level"* ]]; then
thermal=$(echo "$line" | awk -F': ' '{print $2}')
# 输出一行数据
if [[ -n "$cpu" || -n "$gpu" || -n "$ane" ]]; then
timestamp=$(date "+%H:%M:%S")
if [[ "$powerConsumptionPerHour" == "true" ]]; then
printf "%-8s | %-8s | %-8s | %-8s | %-8s | %-8s | %s\n" \
"$timestamp" "${cpu:-N/A}" "${gpu:-N/A}" "${ane:-N/A}" "${combined:-N/A}" "${thermal:-N/A}" "${power_consumption:-N/A}"
else
printf "%-8s | %-8s | %-8s | %-8s | %-8s | %s\n" \
"$timestamp" "${cpu:-N/A}" "${gpu:-N/A}" "${ane:-N/A}" "${combined:-N/A}" "${thermal:-N/A}"
fi
fi
# 重置变量
cpu=""
gpu=""
ane=""
combined=""
thermal=""
power_consumption=""
fi
done
}
fi可配置统计单位,刷新频率,是否统计千瓦时(度)
并且提供简洁与美观(更详细的)
统计千瓦时仅在美观显示下才有
以下是两种效果的展示


使用方法:
打开终端输入
vim <文件名>复制上述代码粘贴进去
按下esc后输入
:wq保存并退出
之后直接双击这个文件就可以使用了,效果如下
