[Mac] 用 shell script + cron job 定期檢查 CPU 使用率,提醒高耗電元兇
最近突然發現,有時候 Mac 的電量耗的很快,
查了一下,通常是 Chrome 裡某個網頁 CPU 使用率非常高,
或者是某個擴充功能出了問題…
用 top 指令或是 Activity Monitor 可以找出元兇,
但有時候是電量耗掉很多之後才發現,
於是想寫一個小程式來監測一下 CPU 的使用率~
這個小程式的想法很簡單:
- 用 cron job 每 5 分鐘跑一次小程式
- 小程式起來後,每 10 秒檢查一下 CPU,共檢查 6 次 (也就是 1 分鐘)
- 如果這 6 次檢查,CPU 使用率都高於 90%,就彈出警告
- 不管檢查結果如何,6 次檢查 (1 分鐘) 後,小程式就結束了
就來一步步寫程式吧~
1. 設定 cron job 定期啟動小程式
執行 crontab -e 來編輯 cron job,
設定每 5 分鐘就執行一次 alert_cpu_high.sh:
#MIN HOUR DAY MONTH DAYOFWEEK COMMAND */5 * * * * ~/Dropbox/alert_cpu_high.sh
2. 檢查 CPU 使用率
這邊是小程式的內容,基本上就是用 ps 找出 CPU 使用率最高的一個 process,
看看 CPU 使用率是不是超過 90,是的話就計數加 1。
如果計數 6 次都超過,就顯示一個對話框提醒:
#!/bin/sh CPU_USAGE_THRESHOLD=90 ALERT_THRESHOLD=6 COUNT=0 EXCEED_THRESHOLD_COUNT=0 if ps aux | egrep -v grep | egrep -q "display dialog.*CPU usage too high"; then echo "Other instances are runing. Quit now." exit fi while [ "${COUNT}" -lt "${ALERT_THRESHOLD}" ] do COUNT=$((COUNT+1)) # Get highest cpu usage line TOP_CPU_USAGE_PS=$(ps aux -r | head -n 2 | tail -n 1) # Get highest cpu usage CUR_CPU_USAGE=$(echo "${TOP_CPU_USAGE_PS}" | awk '{print $3}') # Convert to integer CUR_CPU_USAGE=$(printf '%.0f' "${CUR_CPU_USAGE}") if [ "${CUR_CPU_USAGE}" -ge "${CPU_USAGE_THRESHOLD}" ]; then # Increment count EXCEED_THRESHOLD_COUNT=$((EXCEED_THRESHOLD_COUNT+1)) if [ "${EXCEED_THRESHOLD_COUNT}" -ge "${ALERT_THRESHOLD}" ]; then # Show alert osascript -e "display dialog \"${TOP_CPU_USAGE_PS}\" with title \"CPU usage too high\"" break fi fi sleep 10 done
上面的小程式裡面,我新學到的部分是利用 printf 來將浮點數轉成整數,
這是因為 shell 只能對整數比較大小~
將格式符號設定成 “%.0f”,這樣像 98.3 的使用率就會被轉成 98 了:
printf '%.0f' "${CUR_CPU_USAGE}"
另一個學到的部分是利用 AppleScript 指令,來顯示提醒或對話框~
用 display dialog 可以顯示一個對話框:
osascript -e "display dialog \"...message...\" with title \"...title...\""
這個對話框要按下 Cancel 或 OK 鈕才能結束
(也可以加上 giving up after 5 在 5 秒後自動關閉)~
另外一種形式是 notification 提醒,
只要把 display dialog 換成 display notification 就行了。
只是 notification 的缺點是一閃而過,沒注意到的話就漏了:
寫好小程式 + 設定 cron job 之後,
只要有 CPU 使用率異常飆高的狀況發生,就會在幾分鐘內收到提醒,
我們就能去關閉相關的 process 或 Chrome 上的分頁/擴充功能,
讓 Mac 電量不再被莫名的耗光光囉~
參考資料:
How to convert floating point number to integer?