-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinfo_notebooks.sh
More file actions
executable file
·139 lines (128 loc) · 5.55 KB
/
info_notebooks.sh
File metadata and controls
executable file
·139 lines (128 loc) · 5.55 KB
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
#!/bin/bash
# --- Forzar formato numérico estándar ---
export LC_NUMERIC="C"
# Script UNIVERSAL y COMPATIBLE (v10) que genera un informe en JSON.
# Utiliza un parser de lshw con búsqueda profunda para máxima compatibilidad.
# Requiere 'jq' y 'lshw'. Uso: sudo ./info_notebooks.sh
# --- Verificación de Dependencias ---
if [ "$EUID" -ne 0 ]; then
echo "{\"error\": \"Este script debe ser ejecutado con sudo.\"}" >&2
exit 1
fi
if ! command -v jq &> /dev/null; then
echo "{\"error\": \"El comando 'jq' no está instalado. Por favor, ejecútalo: sudo apt install jq\"}" >&2
exit 1
fi
if ! command -v lshw &> /dev/null; then
echo "{\"error\": \"El comando 'lshw' no está instalado. Por favor, ejecútalo: sudo apt install lshw\"}" >&2
exit 1
fi
# --- Recolección de Datos Generales ---
serial_number=$(dmidecode -s system-serial-number)
if [ -z "$serial_number" ] || [[ "$serial_number" == *" "* ]]; then
output_filename="info_report.json"
else
output_filename="info_${serial_number}.json"
fi
system_model=$(dmidecode -s system-product-name)
uptime_p=$(uptime -p | sed 's/up //')
load_avg_raw=$(uptime | awk -F'load average: ' '{print $2}')
load_avg_1m=$(echo $load_avg_raw | awk -F', ' '{print $1}')
load_avg_5m=$(echo $load_avg_raw | awk -F', ' '{print $2}')
load_avg_15m=$(echo $load_avg_raw | awk -F', ' '{print $3}')
cpu_model=$(lscpu | grep "Model name:" | sed 's/Model name:[ \t]*//')
cpu_threads=$(lscpu | grep "^CPU(s):" | sed 's/CPU(s):[ \t]*//')
TEMPERATURE_THRESHOLD=65.0
high_temp_alert="null"
temps_raw=$(cat /sys/class/hwmon/hwmon*/temp*_input 2>/dev/null)
readings=()
is_high=false
for temp in $temps_raw; do
temp_c=$(awk -v t="$temp" 'BEGIN {printf "%.1f", t/1000}')
readings+=("$temp_c")
if (( $(echo "$temp_c > $TEMPERATURE_THRESHOLD" | bc -l) )); then
is_high=true
fi
done
if $is_high; then
high_temp_readings=$(printf '%s\n' "${readings[@]}" | jq -R . | jq -s .)
high_temp_alert=$(jq -n --argjson r "$high_temp_readings" '{ "alert": "Temperatura elevada detectada (superior a 65.0°C)", "readings_celsius": $r }')
fi
disk_usage_root=$(df -P / | tail -n 1 | awk '{print $5}')
storage_info=$(lsblk -b -J -o NAME,TYPE,SIZE,MODEL)
ram_line=$(free -b | grep "^Mem:")
ram_total_gib=$(echo "$ram_line" | awk '{printf "%.2f", $2/1073741824}')
ram_used_gib=$(echo "$ram_line" | awk '{printf "%.2f", $3/1073741824}')
ram_available_gib=$(echo "$ram_line" | awk '{printf "%.2f", $7/1073741824}')
swap_line=$(free -b | grep "^Swap:")
swap_total_gib=$(echo "$swap_line" | awk '{printf "%.2f", $2/1073741824}')
swap_used_gib=$(echo "$swap_line" | awk '{printf "%.2f", $3/1073741824}')
swap_free_gib=$(echo "$swap_line" | awk '{printf "%.2f", $4/1073741824}')
max_capacity=$(dmidecode -t memory | grep "Maximum Capacity" | awk -F': ' '{print $2}')
total_slots=$(dmidecode -t memory | grep "Number Of Devices" | awk -F': ' '{print $2}')
# --- Lógica de Hardware de RAM (v10, usando lshw -json con búsqueda profunda) ---
# Este es el método más robusto. Busca en todo el reporte de lshw los objetos
# que parezcan módulos de memoria y extrae sus datos.
ram_slots_json=$(lshw -json -class memory 2>/dev/null | jq '[
.. | objects | select(
.class? == "memory" and
(.id? | test("bank|dimm")) and
.size?
)
] | map({
locator: (.slot // "N/A"),
size: (if .size then "\(.size / 1073741824 | round) GB" else "N/A" end),
type: (.description // "N/A"),
speed: (if .clock then "\(.clock / 1000000 | round) MT/s" else "N/A" end),
part_number: (.product // "N/A"),
serial_number: (.serial // "N/A"),
rank: "N/A"
})')
unique_size_count=$(echo "$ram_slots_json" | jq -r '.[].size' | grep -v "N/A" | sort -u | wc -l)
is_asymmetric=false
if [ "$unique_size_count" -gt 1 ]; then
is_asymmetric=true
fi
# --- Ensamblaje Final con JQ ---
jq -n \
--arg sn "$serial_number" \
--arg model "$system_model" \
--arg uptime "$uptime_p" \
--arg la1 "$load_avg_1m" \
--arg la5 "$load_avg_5m" \
--arg la15 "$load_avg_15m" \
--arg cpu_model "$cpu_model" \
--arg cpu_threads "$cpu_threads" \
--argjson temp_alert "$high_temp_alert" \
--argjson storage "$storage_info" \
--arg disk_usage "$disk_usage_root" \
--arg ram_total "$ram_total_gib" \
--arg ram_used "$ram_used_gib" \
--arg ram_avail "$ram_available_gib" \
--arg swap_total "$swap_total_gib" \
--arg swap_used "$swap_used_gib" \
--arg swap_free "$swap_free_gib" \
--arg max_mem "$max_capacity" \
--arg num_slots "$total_slots" \
--argjson asymmetric "$is_asymmetric" \
--argjson slots "$ram_slots_json" \
'{
"report_timestamp": (now | todate),
"system_info": { "model": $model, "serial_number": $sn },
"performance": { "uptime": $uptime, "load_average": { "1_min": ($la1 | tonumber), "5_min": ($la5 | tonumber), "15_min": ($la15 | tonumber) }, "temperature_alert": $temp_alert },
"cpu": { "model": $cpu_model, "threads": ($cpu_threads | tonumber) },
"storage": { "physical_devices": $storage.blockdevices, "root_filesystem_usage": $disk_usage },
"memory": {
"usage": {
"ram_gib": { "total": ($ram_total | tonumber), "used": ($ram_used | tonumber), "available": ($ram_avail | tonumber) },
"swap_gib": { "total": ($swap_total | tonumber), "used": ($swap_used | tonumber), "free": ($swap_free | tonumber) }
},
"hardware": {
"max_capacity_supported": $max_mem,
"total_slots": ($num_slots | tonumber),
"asymmetric_configuration_warning": $asymmetric,
"installed_slots": $slots
}
}
}' > "$output_filename"
echo "✅ Informe guardado exitosamente en el archivo: $output_filename"