“La potenza è nulla senza il controllo”
L’utente medio di computer utilizza Windows o il MAC per la propria semplicità di interazione attraverso una interfaccia grafica ben progettata. L’interfaccia grafica di Linux, diciamocelo, non è all’altezza delle altre due, né graficamente né a livello di interazione. È senz’altro vero che chi usa Linux fa grande uso della command line, real men don’t use GUIs. Questo significa che l’accesso alla lettura dei parametri di funzionamento della nostra Linux box non è sempre semplice come cliccare un pulsante.
Di positivo, però, dobbiamo dire che, una volta compreso dove e come andare a cercare le informazioni, tutto diventa più semplice: il classico concetto Unix (e Linux) per cui “ogni parametro di sistema è assimilabile ad un file” rende i concetti di controllo estremamente lineari e fluidi. Soprattutto quando dobbiamo intervenire sul nostro SBC, sia esso Raspberry PI o Jetson o altro, avere a disposizione un sistema di acquisizione di parametri univoco e diretto aiuta molto. Infatti gli accessi per le configurazioni vengono eseguiti di norma attraverso secure shell (SSH), che predilige l’uso della linea di comando.
Per tale ragione, in quest’articolo presenteremo una serie di comandi per acquisire informazioni sui parametri di funzionamento del nostro sistema, raggruppandoli poi in un unico script da lanciare su di un qualsiasi sistema Linux.
Controllo della temperatura
1 |
gawk '{ printf("Temperatura : %6.3f°C\n",$1/1000) }' /sys/class/thermal/thermal_zone0/temp |
Il linguaggio AWK è un linguaggio di scripting data-driven che consiste in una serie di azioni da intraprendere nei confronti di flussi di dati testuali. Lo scopo è evidentemente quello di estrarre o modificare il testo. ad esempio per produrre report ben formattati. Il linguaggio usa in modo estensivo tipi stringa, array associativi e regular expressions. Sebbene AWK sia stato definito per creare programmi efficienti di una linea, il linguaggio stesso è Turing-completo. AWK è stato creato nei Bell Labs negli Anni Settanta, ed il nome deriva dai cognomi dei suoi autori: Alfred Aho, Peter Weinberger, e Brian Kernighan.
La GNU foundation ha prodotto la propria release di awk, chiamata gawk (GNU awk). Il manuale dei comandi di gawk si trova a questo link.
Passiamo ad esaminare il comando. Il sistema operativo Linux inserisce regolarmente la temperatura della CPU all’interno della directory /sys/class/thermal/thermal_zone0/ nel file temp.
Eseguendo il comando
1 |
cat /sys/class/thermal/thermal_zone0/temp |
noterermo però che la temperatura ci viene fornita in millesimi di grado: dovremo dividere per 1000 per ottenere l’esatto valore in gradi centigradi.
Il comando richiamato da gawk si occupa proprio di questo: prende in input il contenuto del file temp posto nella directory suddetta, crea una stringa preformattata con il valore “Temperatura : ” ed un segnaposto per il valore, e infine sostituisce al segnaposto il valore letto dal file, dopo averlo diviso per 1000.
Frequenza di lavoro dei cores
Il sistema operativo tende ad abbassare la frequenza di lavoro dei cores quando si trovi in modalità idle (per rismarmiare energia), o in caso di temperatura eccessivamente elevata (per salvaguardare la CPU). Il comando
1 |
cat /sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq |
ci mostra la frequenza di lavoro attuale di ciascun core. La sintassi “cpu?” significa “cicla su tutte le cartelle con nome cpu più un altro carattere, ad esempio cpu0, cpu1, cpu2” e così via.
Un sistema con quattro cores da 1.2 GHz avrà il seguente risultato:
1 2 3 4 |
1200000 1200000 1200000 1200000 |
vale a dire una lista di quattro elementi. Da notare che in questo caso l’unità di misura è il kHz, e per ottenerre il valore in GHz dovremo dividere per 1.000.000. Porebbe tornarci utile gawk.
Il comando da utilizzare sarà il seguente:
1 |
cat /sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq | gawk '{ printf("CPU #%i : %6.2f GHz\n",i++, $1/1000000) }' |
Il simbolo “|” rappresenta la “pipe”, e significa “passa l’output del comando alla sinistra del simbolo come input per il comando posto alla destra del simbolo”.
Ciascuno dei quattro valori recuperati con il comando cat viene fornito a gawk, che lo inserirà nella stringa preformattata dopo averlo diviso per 1.000.000. In aggiunta, una variabile i parte dal valore 0 e viene incrementata dopo la stampa di ciascuna linea per fornire un identificativo dei processori. Il risultato sarà il seguente:
1 2 3 4 |
CPU #0 : 1.20 GHz CPU #1 : 1.20 GHz CPU #2 : 1.20 GHz CPU #3 : 1.20 GHz |
Lista dei processori presenti
Questa istruzione può apparire ridondante dopo il comando precedente, ma è utile per illustrare un paio di punti.
1 |
cat /proc/cpuinfo | grep processor |
Il primo punto è la presenta della directory /proc. Come vedremo più avanti, in essa sono presenti informazioni relative a diversi parametri di funzionamento del nostro sistema. In particolare, /proc/cpuinfo contiene molteplici informazioni relative alla nostra CPU ed ai relativi cores (di seguito un esempio).
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 |
cat /proc/cpuinfo processor : 0 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 1 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 2 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 3 BogoMIPS : 38.40 Features : fp asimd evtstrm crc32 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 |
Quel che a noi interessa è riportare la riga relativa al processore. Per tale motivo utilizziamo il comando grep (Gnu Regular Expression Processor). grep filtra la lista prodotta da cat ed estrae unicamente le righe in cui è presente il termine “processor”.
Stato della memoria fisica
Già che ci siamo, utilizziamo la directory /proc per controllare lo stato della nostra memoria fisica:
1 |
cat /proc/meminfo | grep Mem |
Lascio al sistemista coscienzioso il test della procedura nella stessa modalità del comando precedente.
Il comando riporta lo stato di memoria totale, utilizzata e disponibile:
1 2 3 |
MemTotal: 937280 kB MemFree: 509116 kB MemAvailable: 829052 kB |
Descrizione del sistema audio
Questo comando ha una utilità piuttosto scarsa a livello di testing dei parametri di funzionamento. Abbiamo voluto aggiungerlo per mostrare quante informazioni siano effettivamente disponibili nella directory /proc:
1 |
cat /proc/asound/version |
Partizioni di sistema
Ben più interessante, a mio avviso, il controllo delle partizioni presenti nel nostro disco di sistema:
1 |
cat /proc/partitions |
Attraverso lo studio del contenuto di questo file sarà possibile intuire diversi dettagli relativi all’implementazione del sistema sui nostri SBC.
Carico CPU
Nel file loadavg della directory /proc è anche presente il valore statistico del carico della CPU. Viene riportato il carico nell’ultimo minuto, negli ultimi 5 minuti e negli ultimi 15 minuti. Il comando
1 |
gawk '{ printf("Load average :\n 1 minuto : %3.2f%%\n 5 minuti : %3.2f%%\n 15 minuti : %3.2f%%\n",$1*100/4, $2*100/4, $3*100/4) }' /proc/loadavg |
estrae tali valori e li stampa in una stringa preformattata. Nel nostro caso ho diviso tali valori per il numero di cores presenti, per avere un risultato in percentuale di carico di sistema (0% – 100%). I valori finali, in virgola mobile, sono stati riformattati per avere due sole cifre decimali (%3.2f). Da notare che loadavg presenta i valori su di un’unica linea. gawk li ha separati estraendoli come parametro $1, $2 e $3.
Uptime
Il comando Linux uptime definisce il tempo trascorso dall’ultimo reboot, gli utenti collegati al sistema ed il carico medio di sistema dall’ultima accensione. Sono parametri utili per stabilire lo stato e le attività in essere sul nostro computer.
Ho inserito tutti questi comandi in un’unico shell script, ed il risultato è il seguente:
Il risultato è relativo al mio Raspberry PI 3, con quattro programmi di calcolo che ne sfrtuttano interamente la CPU.
Avremmo potuto aggiungere altre informazioni, come il carico di rete, la configurazione WiFi o la potenza di calcolo in MIPS. Tuttavia il concetto fondamentale è capire dove reperire le informazioni necessarie. Magari in un altro articolo tratteremo di parametri più dinamici.
Il sorgente dello script completo è disponibile su GitHub a questo indirizzo. Lo script è facilmente estendibile, ad esempio per il monitoraggio di sensori esterni. Se avete idee per rendere lo script più utile, o aggiungere parametri importanti, scrivetemi: le soluzioni migliori verranno pubblicate.