Linux: script bash per conoscere e controllare l’hardware del proprio PC

Devil Tux
Devil Tux

La conoscenza dei dati hardware del proprio computer è spesso vaga, invece alcuni di questi sono davvero importanti per diversi aspetti. La conoscenza per esempio del tipo di processore, della dimensione della memoria RAM, della capacità dell’hard-disk sono utili per sapere se un certo software potrà essere installato sulla macchina, il numero seriale della motherboard, quello dell’hard-disk e gli indirizzi MAC delle schede di rete potranno essere utili in caso di furto per un’efficace ricerca ed identificazione. Conoscere infine i dati S.M.A.R.T. aiuta a non trovarsi da un momento all’altro con un hard-disk inservibile.

Questo sito You-hacker.com è dedicato proprio alle finalità sopra descritte. E’ infatti possibile scaricare un software per Windows che esegue una veloce scansione del PC ed invia i dati raccolti al sito che li memorizza e li ripropone all’utente in forma di tabella, mantenendone traccia attraverso l’utilizzo di cookies. E’ possibile anche registrarsi, per avere la sicurezza di essere identificati utilizzando browser differenti e poter stampare su PDF la tabella dei dati personalizzati.

Ho pensato di realizzare uno script che generasse un output CSV simile a quello del software per Windows di You-hacker, per permettere anche agli utenti Linux, non solo di avere un rapporto abbastanza dettagliato dei dati hardware della propria macchina, ma anche di poter usufruire del servizio di conservazione dei dati fornito da You-hacker.

Va detto che non tutte le distribuzioni Linux saranno in grado di far girare lo script, in quanto questo si basa sulla presenza di almeno 3 pacchetti indispensabili:

  • dmidecode (Recupera informazioni hardware direttamente da BIOS) Nello script è stato utilizzato principalmente per registrare le informazioni inventariali come numero di serie del PC, della Motherboard e dello chassis e infine per i dati sul processore. E’ velocissimo perché legge dati pre-registrati.
  • lspci (Elenca le periferiche su Bus PCI)
  • lshv (Legge in maniera dettagliata l’esatta configurazione di tutto l’hardware) Nello script è stato utilizzato con parsimonia perché l’esecuzione è piuttosto lenta. Però l’accuratezza delle informazioni è stata utile per registrare i dati della memoria RAM slot per slot e il dettaglio delle schede di rete

e uno a scelta fra:

  • smartctl (preferibilmente: legge oltre ai dati dell’hard-disk anche i dati S.M.A.R.T. ) Questo programma è davvero utilissimo. Fra gli altri dati fornisce il tempo di accensione dell’hard-disk, la temperatura rilevata, i settori riallocati e i settori pendenti (danneggiati in attesa di essere riallocati)
  • hdparm (Legge i dati dell’hard-disk) Questo è la “ruota di scorta” di Smartmontools, in effetti non fornisce i dati S.M.A.R.T. ma solo la marca, la capacità dell’hard-disk. Questo per lo scopo di questo script, in realtà con hdparm è anche possibile cambiare totalmente i settaggi del disco e visto che si potrebbero fare danni seri, va usato con discernimento.

Ho testato lo script su alcune versioni di Ubuntu (10.04, 11.10 e 12.04) e su tutte e tre funziona correttamente. Su Debian e su CentOS è necessario installare i pacchetti mancanti. Per avere Smartmontools (il software che si occupa di leggere i dati S.M.A.R.T. dell’hard-disk) su Ubuntu è sufficiente fare:

sudo apt-get install smartmontools

oppure seguire questa guida: https://help.ubuntu.com/community/Smartmontools

Ed ecco il codice:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/bin/bash
#!/bin/bash
# Shell script to collect HW information
# For more info please see (Installation info):
# http://www.spadamar.com
# Last updated: May - 2013
# --------------------------------------------------------------------
# This is a free shell script under GNU GPL version 2.0 or above
# Copyright (C) 2013 Mario Spada
# Feedback/comment/suggestions : http://www.spadamar.com
# --------------------------------------------------------------------
 
if ! type "dmidecode" > /dev/null 2>&1; then
	echo "dmidecode non è installato!"
	exit 0
fi
 
if ! type "lspci" > /dev/null 2>&1; then
	echo "lspci non è installato!"
	exit 0
fi
 
if ! type "lshw" > /dev/null 2>&1; then
	echo "lshw non è installato!"
	exit 0
fi
 
if ! (type "smartctl" > /dev/null 2>&1;) && ! (type "hdparm" > /dev/null 2>&1;) then
	echo "Né smartctl né hdparm sono installati!"
	exit 0
fi
 
dateStart=$(date +"%s")
 
fn="hwinfo.csv"
 
echo "Lettura dati S.O., PC name e kernel version..."
 
uname -s | sed 's/^/Operating system;/' > $fn
uname -n | sed 's/^/PC name;/' >> $fn
uname -r | sed 's/^/Kernel version;/' >> $fn
 
echo "Lettura dati distribuzione Linux..."
cat /etc/*-release |grep DISTRIB_DESCRIPTION | sed 's/DISTRIB_DESCRIPTION=/Linux distro;/g' >> $fn
 
echo "Lettura dati BIOS..."
dmidecode -s bios-vendor | sed 's/^/BIOS vendor;/' >> $fn
dmidecode -s bios-version | sed 's/^/BIOS version;/'  >> $fn
dmidecode -s bios-release-date | sed 's/^/BIOS release date;/' >> $fn
dmidecode -s system-manufacturer | sed 's/^/System manufacturer;/' >> $fn
dmidecode -s system-product-name | sed 's/^/System product name;/' >> $fn
dmidecode -s system-serial-number | sed 's/^/System serial number;/' >> $fn
dmidecode -s system-uuid | sed 's/^/System UUID;/' >> $fn
dmidecode -s baseboard-manufacturer | sed 's/^/Motherboard manufacturer;/' >> $fn
dmidecode -s baseboard-product-name | sed 's/^/Motherboard product name;/' >> $fn
dmidecode -s baseboard-version | sed 's/^/Motherboard version;/' >> $fn
dmidecode -s baseboard-serial-number | sed 's/^/Motherboard serial number;/' >> $fn
dmidecode -s chassis-manufacturer | sed 's/^/Chassis manufacturer;/' >> $fn
dmidecode -s chassis-type | sed 's/^/Chassis type;/' >> $fn
dmidecode -s chassis-serial-number | sed 's/^/Chassis serial number;/' >> $fn
dmidecode -s processor-manufacturer | sed 's/^/Processor manufacturer;/' >> $fn
dmidecode -s processor-version | sed 's/^/Processor version;/' >> $fn
dmidecode -s processor-frequency | sed 's/^/Processor frequency;/' >> $fn
 
# lspci -mmv 
echo "Lettura dati periferiche PCI..."
pre=""
res=""
lspci -mmv |
while read line
do
	if [[ "$line" == *"Class"* ]] || [[ "$line" == "Vendor"* ]] || [[ "$line" == "Device"* ]]; then
		if [[ "$line" == *"Class"* ]]; then
			pre=$( echo $line | sed 's/Class:[ ^t]*//g' )
		else
			line=$( echo $line | sed 's/:/;/g' |  sed 's/#/n\./g' )
			res=$pre" "$line
			if [[ ! "$res" == "Ethernet"* ]] && [[ ! "$res" == "Network"* ]]; then
				echo $res >> $fn
			fi
		fi
	fi
done
echo "Lettura dati periferiche Networking e Memoria RAM (potrebbe essere lento)..."
#lshw -class network -class memory
pre=""
res=""
lshw -class network -class memory | 
while read line
do
	if [[ "$line" == *"description:"* ]] || [[ "$line" == "product:"* ]] || [[ "$line" == "vendor:"* ]] \
		|| [[ "$line" == "logical name:"* ]] || [[ "$line" == "serial:"* ]]  || [[ "$line" == "size:"* ]] \
		|| [[ "$line" == "slot:"* ]] ; then
		if [[ "$line" == *"description"* ]]; then
			pre=$( echo $line | sed 's/description:[ ^t]*//g' )
		else
			line=$( echo $line | sed 's/: /;/g' )			
			res=$pre" "$line
			echo $res >> $fn
		fi
	fi
done
 
mpMainHd=$(df -Hl | grep ^\/dev.*\/$ | cut -c 1-8)
 
echo "Individuato: "$mpMainHd" come punto di montaggio dell'HDD principale..."
 
if (type "smartctl" > /dev/null 2>&1;) then
	echo "Lettura dati Hard-disk e S.M.A.R.T. con smartmontools..."	
	smartctl -i $mpMainHd | 
	while read line
	do
		if [[ "$line" == "Model Family"* ]] || [[ "$line" == "Device Model"* ]]	|| [[ "$line" == "Serial Number"* ]] \
			|| [[ "$line" == *"Firmware"* ]] || [[ "$line" == *"Capacity"* ]]; then
			line=$( echo $line | sed 's/: /;/g' )
			echo "HDD "$line >> $fn
		fi
	done
 
	smartctl -A $mpMainHd | sed -n '/RAW_VALUE/,/^$/p' | sed 1d |
	while IFS=" " read -r -a line; 
	do
		nb=${#line[@]}
		if [[ "$nb" > 0 ]]; then
			pre=$( echo ${line[$((nb - 9))]} | sed 's/_/ /g' )			
			echo "HDD SMART "$pre";"${line[$((nb - 1))]} >> $fn
		fi
	done
else
	echo "Lettura dati Hard-disk con hdparm..."
	hdparm -I $mpMainHd | sed -n '/ATA device/,/Commands\/features:/p' | 
	while read line 
	do
		if [[ "$line" == *"Model Number:"* ]]; then
			echo $line | sed 's/: /;/g' | sed 's/^/HDD /' >> $fn
		fi
		if [[ "$line" == *"Serial Number:"* ]]; then
			echo $line | sed 's/: /;/g' | sed 's/^/HDD /' >> $fn
		fi
		if [[ "$line" == *"Firmware Revision:"* ]]; then
			echo $line | sed 's/: /;/g' | sed 's/^/HDD /' >> $fn
		fi
		if [[ "$line" == *"Transport:"* ]]; then
			echo $line | sed 's/: /;/g' | sed 's/^/HDD /' >> $fn
		fi
		if [[ "$line" == *"device size with M = 1000*1000:"* ]]; then
			echo $line | sed 's/device size with M = 1000\*1000: /Size;/g' | sed 's/^/HDD /' >> $fn
		fi
		if [[ "$line" == *"Nominal Media Rotation Rate:"* ]]; then
			echo $line | sed 's/: /;/g' | sed 's/^/HDD /' >> $fn
		fi
	done
fi
 
date | sed 's/^/Scan date;/' >> $fn
dateStop=$(date +"%s")
diff=$(($dateStop-$dateStart))
echo "Elapsed time; $(($diff / 60)) minutes and $(($diff % 60)) seconds." >> $fn
 
echo "il file: "$fn" è stato generato!"
 
exit 0

E questo è l’elenco dei parametri rilevati:

Operating system, PC name, Kernel version, Linux distro, BIOS vendor, BIOS version, BIOS release date, System manufacturer, System product name, System serial number, System UUID, Motherboard manufacturer, Motherboard product name, Motherboard version, Motherboard serial number, Chassis manufacturer, Chassis type, Chassis serial number, Processor manufacturer, Processor version, Processor frequency, Host bridge Vendor, Host bridge Device, VGA compatible controller Vendor, VGA compatible controller Device, Communication controller Vendor, Communication controller Device, USB Controller Vendor, USB Controller Device, Audio device Vendor, Audio device Device, PCI bridge Vendor, PCI bridge Device, PCI bridge Vendor, PCI bridge Device, PCI bridge Vendor, PCI bridge Device, PCI bridge Vendor, PCI bridge Device, PCI bridge Vendor, PCI bridge Device, USB Controller Vendor, USB Controller Device, ISA bridge Vendor, ISA bridge Device, IDE interface Vendor, IDE interface Device, SMBus Vendor, SMBus Device, IDE interface Vendor, IDE interface Device, USB Controller Vendor, USB Controller Device, L1 cache slot, L1 cache size, L2 cache slot, L2 cache size, L3 cache slot, L3 cache size, System Memory slot, System Memory size, Ethernet interface product, Ethernet interface vendor, Ethernet interface logical name, Ethernet interface serial, Ethernet interface size, Wireless interface product, Wireless interface vendor, Wireless interface logical name, Wireless interface serial, HDD Model Family, HDD Device Model, HDD Serial Number, HDD Firmware Version, HDD User Capacity, HDD SMART Raw Read Error Rate, HDD SMART Spin Up Time, HDD SMART Start Stop Count, HDD SMART Reallocated Sector Ct, HDD SMART Seek Error Rate, HDD SMART Power On Hours, HDD SMART Spin Retry Count, HDD SMART Calibration Retry Count, HDD SMART Power Cycle Count, HDD SMART G-Sense Error Rate, HDD SMART Power-Off Retract Count, HDD SMART Load Cycle Count, HDD SMART Temperature Celsius, HDD SMART Reallocated Event Count, HDD SMART Current Pending Sector, HDD SMART Offline Uncorrectable, HDD SMART UDMA CRC Error Count, HDD SMART Multi Zone Error Rate, HDD SMART Head Flying Hours, HDD SMART Total LBAs Written, HDD SMART Total LBAs Read, HDD SMART Free Fall Sensor, Scan date, Elapsed time

Per manipolare l’output e formattarlo correttamente per il CSV (hwinfo.csv) ho utilizzato il pipe con i comandi sed e grep. Lo script riconosce se i pacchetti indispensabili sono installati e in caso contrario, termina senza produrre output, riconosce anche l’hard-disk dove è montata la partizione root /

Consiglio in particolare di controllare il numero di HDD SMART Reallocated Sector se questi sono più di zero, l’hard-disk è a rischio, soprattutto se ripetendo le scansioni il valore aumenta. In questi casi è consigliabile la sostituzione!

Potete scaricare lo script in formato compresso tar.gz qui