顯示OpenWrt路由器或Linux裝置的狀態(一):基本命令

我打算在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裡面包含一行用空格分開的兩項(或者說兩欄)資料:

uptime檔

在電腦上透過ssh命令連線(參閱「創想三維(Creality)K1 SE 3D列印機(二)」以及「從VS Code遠端SSH連線、開發Python程式」)至OpenWrt路由器(以紅米AX6000為例),執行底下的cat命令:

cat /proc/uptime

如下圖所示:

cat /proc/uptime命令

它將傳回用空格分開的兩個秒數值:

  • 數字1:運作時間
  • 數字2:閒置時間,代表CPU的所有核心處於閒置(idle)狀態的時間總和。

執行“cat /proc/meminfo”命令可顯示記憶體資訊:

執行“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目錄

thermal_zone0目錄裡面具有temp(溫度)type(類型)虛擬檔案,temp包含即時溫度值,type則包含這個溫度感測器的類型(即:感測來源)。

用cat命令讀取type檔的全部內容,顯示:“cpu-thermal”,代表這個“thermal_zone0”目錄內含的溫度值源自CPU的感測器。

cat  /sys/class/thermal/thermal_zone0/type

cpu-thermal檔

用cat命令讀取此路徑的temp檔,即可獲取CPU的即時溫度:

cat  /sys/class/thermal/thermal_zone0/temp

temp檔

temp資料單位是「毫攝氏度」,將該值除以1000才是以°C為單位的實際溫度。所以45385,代表CPU為45.385°C。

智慧型手機、樹莓派和香橙派等裝置的處理器內部有多個溫度感測器,例如,樹莓派和香橙派有兩種溫度感測器來源,分別位於thermal_zone0和thermal_zone1目錄,底下命令將顯示它們的類型:

thermal_zone0和thermal_zone1目錄

因此,底下命令可取得CPU和GPU溫度值:

cat  /sys/class/thermal/thermal_zone0/temp
cat  /sys/class/thermal/thermal_zone1/temp

取得CPU溫度值

上面兩種溫度的檔案路徑,只差在編號不同(0和1),因此可用‘*’(萬用字元)代表0個或多個字元,或者用’?’代表1個任意字元,像這樣:

cat  /sys/class/thermal/thermal_zone*/temp

一次讀取CPU和GPU溫度數據:

取得CPU和GPU溫度值

用grep命令讀取CPU和GPU的即時溫度值

grep命令可搜尋字串、替換、提取和刪除。grep這個名字源自Linux的文本編輯器“ed”中的指令 g/re/p,代表globally search a regular expression and print(以規則表達式進行全域搜尋以及列印)。

grep命令的基本語法:

grep命令的基本語法

其中的參數:

  • 選項:控制輸出方式或匹配行為,例如,‘-i’代表不區分大小寫。
  • 模式:要搜尋的字串或正則表達式。 
  • 檔案:要搜尋的檔案,若省略則從標準輸入讀取。 

假設作業系統的日誌(/var/log/syslog)包含如下的內容:

syslog檔

底下命令將傳回包含“uart”(忽略大小寫)的所有行:

sudo grep -i 'uart' /var/log/syslog

執行結果會顯示匹配的兩行:

執行grep的結果

底下命令將取得CPU溫度,執行結果跟cat命令一樣:

grep '.'  /sys/class/thermal/thermal_zone0/temp

執行grep的結果

在規則表達式中,’.’可匹配「換行」以外的任何單一字元。因此,’grep . 檔案文件’命令代表:「搜尋並傳回文件各行的每個字。」廣告一下,規則表達式的說明與應用,請參閱《超圖解Python程式設計》第13章。

若搜尋多份文件,‘grep .’會自動在搜尋結果前面加上檔案來源,方便我們識別,以在樹莓派或香橙派執行底下命令為例:

grep '.'  /sys/class/thermal/thermal_zone*/type

結果顯示:

執行grep的結果

在執行Linux系統的Intel/AMD平台上,處理器的溫度資料位於’/sys/class/hwmon/’目錄,感測器類型名稱存在“hwmon編號”的子目錄的name檔案中,以ThinkPad電腦為例:

執行grep的結果

電腦整機溫度以及CPU核心溫度,分別存在“hwmon4”目錄的temp2_input和temp4_input檔。

取得CPU和GPU溫度

補充說明,運行於Windows 11 WSL的Linux系統,Windows沒有把原生電腦的所有硬體感測器資料都傳給虛擬機,只能看到交流電源供應器(AC1)和電池(BAT1)。

Windows 11 WSL的Linux系統

使用awk工具擷取資料

awk命令適合處理「以行為單位、以欄位為結構」的資料,預設分隔符是空白字元或Tab,其名稱源自三位作者:Aho、Weinberger和Kernighan的首字母。awk的功能強大,主要特性:

  • 支援強大的規則表達式
  • 內建變數:$0(代表整行), $1, $2,…(欄位編號), NR(行號)…等。
  • 支援關聯陣列(associative array),也就是以名稱字串而非數字索引元素的陣列。
  • 內建字串處理和數學計算的函式。
  • 支援算術運算子、賦值運算子、比較運算子和邏輯運算子。
  • 支援 if-else, for, while, switch-case…等控制結構。

awk的基本語法:

awk的基本語法

底下命令將讀取 /proc/uptime(開機啟動時間)並顯示它的整行內容(兩個數字值):

awk '{print $0}' /proc/uptime

讀取 /proc/uptime

僅擷取裝置運作時間(即:欄位1資料):

擷取裝置運作時間

透過int()函式取整數值:

使用awk取得記憶體資訊

回顧一下包含記憶體資訊的’/proc/meminfo’檔案,實際的數值位於每一行的第2欄,各欄位用一個以上的空格分開:

meminfo檔

底下的awk命令將透過規則表達式搜尋’/proc/meminfo’檔案中,包含`MemTotal`(總記憶體大小)字串的所有行,並顯示其中的第2欄:

取得MemTotal

執行結果:

取得MemTotal

底下awk命令可取得總記憶體大小並且把KB單位轉換成MB:

把KB單位轉換成MB

Linux命令可分成多行,以執行awk命令取得可用記憶體大小為例:

取得可用記憶體大小

底下這行awk命令將從 “/proc/meminfo” 提取兩欄資料來計算「已使用記憶體百分比」:

awk '/MemTotal/ {t=$2} /MemAvailable/  {a=$2} END { printf "%.1f%%\n", (1 - a/t) * 100}' /proc/meminfo

分開寫成數行比較看得清楚,中間的縮排只是為了方便閱讀,非必要:

計算「已使用記憶體百分比」

執行結果:

計算「已使用記憶體百分比」

先這樣,下回繼續…

Posts created 529

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top