我打算在ESP32上顯示執行OpenWrt系統的路由器的處理器溫度、記憶體用量、運作時間…等資訊。為此,必須在OpenWrt系統上執行一個Linux腳本程式(shell script),取得路由器的狀態。
本文將介紹並運用Linux系統裡的文字處理三寶(命令行工具)擷取並解析路由器資訊:
- cat:顯示或合併檔案內容,不具備過濾功能,原樣輸出整份內容。
- grep:搜尋字串;依模式比對、過濾輸出整行或匹配的片段。
- awk:提取字串;側重欄位(例如,空格或逗號分隔的資料)處理與運算,可輸出匹配的欄位資料或計算結果。
讀取系統的運作狀態資訊
Linux系統當中有個讓使用者和程式存取系統核心(kernel)狀態的虛擬目錄,叫做“/proc” (“proc”意指process,程序),每個執行中的程序都在“/proc底下有個對應的目錄(/proc/程序ID),裡面包含該程序的資訊。
“/proc”也包含一些同樣由系統動態產生虛擬檔案,例如:
- /proc/version:包含系統版本資訊
- /proc/cpuinfo:包含CPU型號、核心數、快取大小等資訊。
- /proc/loadavg:包含系統負載資訊,用於查看CPU是否過載。
- /proc/uptime:包含運作時間(即:自裝置啟動以來的總秒數)以及閒置時間資訊。
- /proc/meminfo:包含記憶體使用狀況資訊。
這些檔案皆可透過Linux系統內建的顯示、合併、建立文件的cat工具(意指“concatenate”,連接)呈現。以查看運作時間為例,uptime裡面包含一行用空格分開的兩項(或者說兩欄)資料:
在電腦上透過ssh命令連線(參閱「創想三維(Creality)K1 SE 3D列印機(二)」以及「從VS Code遠端SSH連線、開發Python程式」)至OpenWrt路由器(以紅米AX6000為例),執行底下的cat命令:
cat /proc/uptime
如下圖所示:

它將傳回用空格分開的兩個秒數值:
- 數字1:運作時間
- 數字2:閒置時間,代表CPU的所有核心處於閒置(idle)狀態的時間總和。
執行“cat /proc/meminfo”命令可顯示記憶體資訊:
其中的前3項:
- MemTotal:記憶體總數。AX6000路由器有512MB DRAM,這裡顯示495876 kB(約484 MB),因某些記憶體保留給開機啟動程式、系統核心、驅動程式…等使用。
- MemFree:實際未分配使用的空閒記憶體,不包括已用於快取(cache)或緩衝區(buffer)的部分。在系統運作期間,此值通常固定不變。
- MemAvailable:應用程式可用的記憶體估值,也就是「RAM使用率」,包含可動態回收的快取或緩衝區,因此比較能確切顯示裝置在記憶體耗盡前實際剩餘的「可用空間」。
用cat命令讀取CPU和GPU的即時溫度值
Linux系統的‘/proc/’目錄存放程序(軟體)的相關資訊,另有一個‘/sys/’目錄存放硬體資訊。例如,openWrt系統路由器的CPU溫度值,以及散熱器的運作狀態,位於這個路徑:
/sys/class/thermal/
使用ls命令列舉此目錄,可看到3個子目錄,cooling_device是散熱裝置,thermal_zone0包含處理器的溫度資訊。
thermal_zone0目錄裡面具有temp(溫度)和type(類型)虛擬檔案,temp包含即時溫度值,type則包含這個溫度感測器的類型(即:感測來源)。
用cat命令讀取type檔的全部內容,顯示:“cpu-thermal”,代表這個“thermal_zone0”目錄內含的溫度值源自CPU的感測器。
cat /sys/class/thermal/thermal_zone0/type
用cat命令讀取此路徑的temp檔,即可獲取CPU的即時溫度:
cat /sys/class/thermal/thermal_zone0/temp
temp資料單位是「毫攝氏度」,將該值除以1000才是以°C為單位的實際溫度。所以45385,代表CPU為45.385°C。
智慧型手機、樹莓派和香橙派等裝置的處理器內部有多個溫度感測器,例如,樹莓派和香橙派有兩種溫度感測器來源,分別位於thermal_zone0和thermal_zone1目錄,底下命令將顯示它們的類型:
因此,底下命令可取得CPU和GPU溫度值:
cat /sys/class/thermal/thermal_zone0/temp cat /sys/class/thermal/thermal_zone1/temp

上面兩種溫度的檔案路徑,只差在編號不同(0和1),因此可用‘*’(萬用字元)代表0個或多個字元,或者用’?’代表1個任意字元,像這樣:
cat /sys/class/thermal/thermal_zone*/temp
一次讀取CPU和GPU溫度數據:
用grep命令讀取CPU和GPU的即時溫度值
grep命令可搜尋字串、替換、提取和刪除。grep這個名字源自Linux的文本編輯器“ed”中的指令 g/re/p,代表globally search a regular expression and print(以規則表達式進行全域搜尋以及列印)。
grep命令的基本語法:

其中的參數:
- 選項:控制輸出方式或匹配行為,例如,‘-i’代表不區分大小寫。
- 模式:要搜尋的字串或正則表達式。
- 檔案:要搜尋的檔案,若省略則從標準輸入讀取。
假設作業系統的日誌(/var/log/syslog)包含如下的內容:
底下命令將傳回包含“uart”(忽略大小寫)的所有行:
sudo grep -i 'uart' /var/log/syslog
執行結果會顯示匹配的兩行:
底下命令將取得CPU溫度,執行結果跟cat命令一樣:
grep '.' /sys/class/thermal/thermal_zone0/temp
在規則表達式中,’.’可匹配「換行」以外的任何單一字元。因此,’grep . 檔案文件’命令代表:「搜尋並傳回文件各行的每個字。」廣告一下,規則表達式的說明與應用,請參閱《超圖解Python程式設計》第13章。
若搜尋多份文件,‘grep .’會自動在搜尋結果前面加上檔案來源,方便我們識別,以在樹莓派或香橙派執行底下命令為例:
grep '.' /sys/class/thermal/thermal_zone*/type
結果顯示:
在執行Linux系統的Intel/AMD平台上,處理器的溫度資料位於’/sys/class/hwmon/’目錄,感測器類型名稱存在“hwmon編號”的子目錄的name檔案中,以ThinkPad電腦為例:
電腦整機溫度以及CPU核心溫度,分別存在“hwmon4”目錄的temp2_input和temp4_input檔。
補充說明,運行於Windows 11 WSL的Linux系統,Windows沒有把原生電腦的所有硬體感測器資料都傳給虛擬機,只能看到交流電源供應器(AC1)和電池(BAT1)。
使用awk工具擷取資料
awk命令適合處理「以行為單位、以欄位為結構」的資料,預設分隔符是空白字元或Tab,其名稱源自三位作者:Aho、Weinberger和Kernighan的首字母。awk的功能強大,主要特性:
- 支援強大的規則表達式
- 內建變數:$0(代表整行), $1, $2,…(欄位編號), NR(行號)…等。
- 支援關聯陣列(associative array),也就是以名稱字串而非數字索引元素的陣列。
- 內建字串處理和數學計算的函式。
- 支援算術運算子、賦值運算子、比較運算子和邏輯運算子。
- 支援 if-else, for, while, switch-case…等控制結構。
awk的基本語法:
底下命令將讀取 /proc/uptime(開機啟動時間)並顯示它的整行內容(兩個數字值):
awk '{print $0}' /proc/uptime
僅擷取裝置運作時間(即:欄位1資料):
透過int()函式取整數值:
使用awk取得記憶體資訊
回顧一下包含記憶體資訊的’/proc/meminfo’檔案,實際的數值位於每一行的第2欄,各欄位用一個以上的空格分開:
底下的awk命令將透過規則表達式搜尋’/proc/meminfo’檔案中,包含`MemTotal`(總記憶體大小)字串的所有行,並顯示其中的第2欄:
執行結果:
底下awk命令可取得總記憶體大小並且把KB單位轉換成MB:
Linux命令可分成多行,以執行awk命令取得可用記憶體大小為例:
底下這行awk命令將從 “/proc/meminfo” 提取兩欄資料來計算「已使用記憶體百分比」:
awk '/MemTotal/ {t=$2} /MemAvailable/ {a=$2} END { printf "%.1f%%\n", (1 - a/t) * 100}' /proc/meminfo
分開寫成數行比較看得清楚,中間的縮排只是為了方便閱讀,非必要:
執行結果:
先這樣,下回繼續…
