Linux informatie script

Geschreven door Sebastiaan Franken op 03-01-2022 03:58 met 2497 woorden en een leestijd van 12 minuten. Getagged met Blog

Soms kom je, via iets of iemand, tot een uitdaging om iets te maken wat je nog nooit gemaakt hebt. Ik had een tijdje geleden zo’n uitdaging: iemand moest, voor zijn/haar opleiding, een informatiescript maken in bash waarin een aantal systeemeigenschappen naar voren kwamen, en waar een aantal statistische dingen naar voren kwamen.

Toen ik deze opdracht zag dacht ik bij mezelf: dit kan ik ook, maar beter. Ik ben aan het schrijven geslagen en het onderstaande script is het (voorlopige) eindresultaat:

  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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#!/bin/bash

LANG=en_US

# A pure bash system information script for laptops, desktops, servers and everything
# else capable of running Linux with bash.

# This function prints X dashes, followed by the provided argument, followed by another
# X dashes.
#
# X is calculated by dividing the number of cols in two (tput cols / 2) and subtracting
# 1 for extra padding between the dashes and the title.
title() {
	titlelength="${#1}"
	((titlelength=titlelength+2))
	maxcols="$(echo "($(tput cols) - ${titlelength}) / 2" | bc)"

	printf "\n"

	# Build the left side dashes
	for i in $(seq 1 ${maxcols}); do
		printf "-"
	done

	printf " %s " "${1}"

	# Build the right side dashes
	for i in $(seq 1 ${maxcols}); do
		printf "-"
	done

	printf "\n\n"
}

# This function is a wrapper around printf with some specific formatting options.
aprintf() {
	# If this is a terminal do a nice coloured/bold output, otherwise don't.
	if [ -t 1 ]; then
		printf "%-54s: %s\n" "${1}" "$(tput bold)${2}$(tput sgr0)"
	else
		printf "%-54s: %s\n" "${1}" "${2}"
	fi
}

# This function is a wrapper around printf() with some specific formatting and length options.
keyvalue() {
	cols="$(echo "($(tput cols) - 2) / 2" | bc)"

	if [ -t 1 ]; then
		printf "%-${cols}s : %s\n" "${1}" "$(tput bold)${2}$(tput sgr0)"
	else
		printf "%-${cols}s : %s\n" "${1}" "${2}"
	fi
}

# This function checks the load average (in /proc/loadavg) and applies colour to
# the output.
format_load_average() {
	db="/proc/loadavg"
	max="$(nproc)"

	f1="$(awk '{print $1}' "${db}")"
	f5="$(awk '{print $2}' "${db}")"
	f15="$(awk '{print $3}' "${db}")"

	_buildlabel() {
		# If this is a terminal do nice colour things, if not just echo the input.
		if [ -t 1 ]; then
			if [ "$(echo "${1} <= ${max}" | bc)" -eq 0 ]; then
				echo "$(tput setaf 1)$(tput bold)${1}$(tput sgr0)"
			else
				echo "$(tput setaf 2)$(tput bold)${1}$(tput sgr0)"
			fi
		else
			echo "${1}"
		fi
	}

	# Generate labels
	label1="$(_buildlabel "${f1}")"
	label5="$(_buildlabel "${f5}")"
	label15="$(_buildlabel "${f15}")"

	printf "%s, %s, %s" "${label1}" "${label5}" "${label15}"
}

# This function checks if ${2} has ${1}
has() {
	if [ $(grep -c "${1}" "${2}") ]; then
		echo "Yes"
	else
		echo "No"
	fi
}

if [[ $(tput cols) -lt 132 ]]; then
	echo " "
	echo "${0} can only run if the number of cols in this shell is 132 or more. Number of cols here is $(tput cols) Exiting."
	echo " "

	exit 1
fi

# This section is basic information and an introduction to this script.
# It prints a mesasge that it will produce more info when called with sudo.
title "Information script"

if (( $(id -u) > 0 )); then
	echo -e "Information:\tthis script shows more information when called with sudo, like so: "
	echo -e "\t\tsudo $(basename ${SHELL}) ${0}"
	echo " "
fi

# The sections this script has get named here.
echo "This script has the following section(s):"
OLDIFS=${IFS}
IFS=$'\n'
for section in $(grep '^title ' ${0} | tail -n +2); do
	printf " - %s\n" "$(echo "${section}" | awk -F\" '{print $2}')"
done
IFS=${OLDIFS}

echo " "

aprintf "Shell used for ${0}" "$(echo ${SHELL})"

# This section is information related to the host OS / computer.
# The following information is printed:
# - Hostname
# - Domainname (if applicable)
# - OS
# - Hardware vendor
# - Hardware model
title "Host information"
aprintf "Hostname" $(hostname -s)

if [[ "$(hostname -d | wc -l)" ]]; then
	aprintf "Domainname" $(hostname -d)
fi

aprintf "OS" $(hostnamectl | grep "Operating System" | cut -d: -f2 | xargs)
aprintf "Hardware vendor" $(hostnamectl | grep "Hardware Vendor" | cut -d: -f2 | xargs)
aprintf "Hardware model" $(hostnamectl | grep "Hardware Model" | cut -d: -f2 | xargs)

# This section shows statistics related to the host:
# - Uptime
# - User(s) logged in
# - Most CPU used by (PID)
# - Most RAM used by (PID)
# - Load average
# - Max load
title "Host statistics"
aprintf "Uptime" "$(uptime -p | cut -d " " -f2-)"
aprintf "User(s) logged in" $(who -u | wc -l)
aprintf "Most CPU used by" "$(ps --no-headers -eo cmd,pid --sort=-%cpu | head -n1 | xargs)"
aprintf "Most RAM used by" "$(ps --no-headers -eo cmd,pid --sort=-%mem | head -n1 | xargs)"
aprintf "Load average" "$(format_load_average)"
aprintf "Max load" "$(nproc)"

# This section shows network information:
# - Number of NICs in the system
# - Information about each NIC
# - - Name
# - - Status
# - - MAC address
# - Default route
title "Network information"
aprintf "Number of NICs" "$(ip -br link | tail -n +2 | wc -l)"

for nic in $(ip -br link | tail -n +2 | awk '{print $1}'); do
	nicname="$(ip -br link show "${nic}" | awk '{print $1}')"
	nicstatus="$(ip -br link show "${nic}" | awk '{print $2}')"
	nicmac="$(ip -br link show "${nic}" | awk '{print $3}')"

	if [ "${nicstatus}" = "UP" ]; then
		ipaddr="$(ip -br addr show "${nic}" | awk '{print $3}' | xargs)"
		if [ -t 1 ]; then
			printf " - %s \t %s \t %s \t %s\n" "${nicname}" "$(tput setaf 2)UP$(tput sgr0)" "${nicmac}" "${ipaddr}"
		else
			printf " - %s \t %s \t %s \t %s\n" "${nicname}" "UP" "${nicmac}" "${ipaddr}"
		fi
	else
		if [ -t 1 ]; then
			printf " - %s \t %s \t %s\n"  "${nicname}" "$(tput setaf 1)DOWN$(tput sgr0)" "${nicmac}"
		else
			printf " - %s \t %s \t %s\n"  "${nicname}" "DOWN" "${nicmac}"
		fi
	fi
done

aprintf "Default route" "$(ip -br route list default | awk '{print $3}')"

# This section shows firewall information, *if* the firewalld service is running
if [[ "$(systemctl --quiet is-active firewalld.service)" -eq 0 ]]; then
	title "Firewall information"
	aprintf "Firewalld zone" "$(firewall-cmd --list-all | head -n1)"

	OLDIFS=${IFS}
	IFS=$'\n'
	for line in $(firewall-cmd --list-all | tail -n +2); do
		key="$(echo ${line} | cut -d: -f1 | xargs)"
		value="$(echo ${line} | cut -d: -f2 | xargs)"
		aprintf "${key}" "${value}"
	done

	IFS=${OLDIFS}
fi

# This section shows memory (RAM/swap) information:
# - Total memory installed
# - Total memory used
# - Memory (RAM) type*
# - Total swap size
# - Total swap used
title "RAM/Swap information"

totalmemory="$(free -g --si | awk '/^Mem/ {print $2}')"
memoryused="$(free -g --si | awk '/^Mem/ {print $3}')"
totalswap="$(free -g --si | awk '/^Swap/ {print $2}')"
swapused="$(free -g --si | awk '/^Swap/ {print $3}')"

aprintf "Total memory installed" "${totalmemory}GB"

if [ -t 1 ]; then
	if (( "${memoryused}" < "${totalmemory}" )); then
		aprintf "Memory used" "$(tput setaf 2)${memoryused}GB$(tput sgr0)"
	else
		aprintf "Memory used" "$(tput setaf 1)${memoryused}GB$(tput sgr0)"
	fi
else
	aprintf "Memory used" "${memoryused}GB"
fi

if (( $(id -u) == 0 )); then
	aprintf "Memory type" "$(dmidecode -t 17 | grep Type: | uniq | cut -d: -f2 | xargs)"
fi

aprintf "Total swap" "${totalswap}GB"

if [ -t 1 ]; then
	if (( "${swapused}" < "${totalswap}" )); then
		aprintf "Swap used" "$(tput setaf 2)${swapused}GB$(tput sgr0)"
	else
		aprintf "Swap used" "$(tput setaf 1)${swapused}GB$(tput sgr0)"
	fi
else
	aprintf "Swap used" "${swapused}GB"
fi

# This section shows CPU information:
# - CPU model name
# - CPU vendor ID
# - CPU bugs*
# - Number of cores
title "CPU information"
aprintf "CPU model name" "$(grep "model name" /proc/cpuinfo | cut -d: -f2 | uniq | cut -d@ -f1 | xargs)"
aprintf "CPU vendor id" "$(grep vendor_id /proc/cpuinfo | cut -d: -f2 | uniq | xargs)"

if (( $(id -u) == 0 )); then
	aprintf "CPU bugs" "$(grep bugs /proc/cpuinfo | cut -d: -f2 | uniq | xargs)"
fi

aprintf "Number of cores" $(nproc)

# This section contains information about the GPU:
# - GPU manufacturer and type
# - Number of GPU(s)
title "GPU information"
aprintf "GPU manufacturer and type" "$(lspci | grep -i vga | awk -F: '{print $3}' | uniq | xargs)"
aprintf "Number of GPUs" "$(lspci | grep -i vga | wc -l)"

# This section contains information about installed system software (packages):
# - Total number of RPM packages installed
# - - List of packages**
# - Total number of repositories installed
# - - List of total repositories installed**
# - Total number of repositories activated
# - - List of total repositories activated**
# - Total number of flatpak upser applications
# - - List of total flatpak user applications**
# - Total number of flatpak user runtimes
# - - List of total flatpak user runtimes**
# - Total number of flatpak system applications
# - - List of total flatpak system applications**
# - Total number of flatpak system runtimes
# - - List of total flatpak system runtimes**
# - Total number of flatpak remotes
# - - List of flatpak remotes**
title "Package information"
aprintf "Total number of packages installed (RPM)" "$(rpm -qa | wc -l)"

if [ "${1}" = "-v" ]; then
	for pkg in $(rpm -qa | sort); do
		printf " - %s\n" "${pkg}"
	done
fi

aprintf "Total number of repositories installed" "$(dnf repolist --all | wc -l)"

if [ "${1}" = "-v" ]; then
	for repo in $(dnf repolist --all | tail -n +2 | awk '{print $1}' | sort); do
		printf " - %s\n" "${repo}"
	done
fi

aprintf "Total number of repositories activated" "$(dnf repolist | wc -l)"

if [ "${1}" = "-v" ]; then
	for repo in $(dnf repolist | tail -n +2 | awk '{print $1}' | sort); do
		printf " - %s\n" "${repo}"
	done
fi

if [[ ! -z "$(rpm -qa flatpak)" ]]; then
	aprintf "Total number of flatpak user applications installed" "$(flatpak list --app --user | wc -l)"

	if [ "${1}" = "-v" ] && [ ! -z "$(flatpak list --app --user)" ]; then
		for flatpakapp in $(flatpak list --app --user | awk '{print $1}' | sort); do
			printf " - %s\n" "${flatpakapp}"
		done
	fi

	aprintf "Total number of flatpak user runtimes installed" "$(flatpak list --runtime --user | wc -l)"

	if [ "${1}" = "-v" ] && [ ! -z "$(flatpak list --runtime --user)" ]; then
		for flatpakruntime in $(flatpak list --runtime --user | awk '{print $1}' | sort); do
			printf " - %s\n" "${flatpakruntime}"
		done
	fi

	aprintf "Total number of flatpak system applications installed" "$(flatpak list --app | wc -l)"

	if [ "${1}" = "-v" ] && [ ! -z "$(flatpak list --app)" ]; then
		for flatpakapp in $(flatpak list --app | awk '{print $1}' | sort); do
			printf " - %s\n" "${flatpakapp}"
		done
	fi

	aprintf "Total number of flatpak system runtimes installed" "$(flatpak list --runtime | wc -l)"

	if [ "${1}" = "-v" ] && [ ! -z "$(flatpak list --runtime)" ]; then
		for flatpakruntime in $(flatpak list --runtime | awk '{print $1}' | sort); do
			printf " - %s\n" "${flatpakruntime}"
		done
	fi

	aprintf "Total number of flatpak remotes installed" "$(flatpak remote-list | tail -n +1 | wc -l)"

	if [ "${1}" = "-v" ] && [ ! -z "$(flatpak remote-list | tail -n +1)" ]; then
		for flatpakremote in $(flatpak remote-list | tail -n +1 | awk '{print $1}' | sort); do
			printf " - %s\n" "${flatpakremote}"
		done
	fi
fi

# This section contains user information:
# - Username
# - User ID
# - Is the user local?
# - Member of group(s)*
# - Home directory
title "User information"
aprintf "Username" "$(whoami)"
aprintf "User ID" "$(id -u)"
aprintf "Local user" "$(has "^$(whoami)" /etc/passwd)"
aprintf "User shell" "$(getent passwd $(whoami) | awk -F: '{print $7}')"

if [ "${1}" = "-v" ]; then
	printf "Member of group(s):\n"

	for groupname in $(groups | tr ' ' '\n' | sort); do
		if [ -t 1 ]; then
			if [ "${groupname}" = "admins" ] || [ "${groupname}" = "sudo" ] || [ "${groupname}" = "wheel" ]; then
				printf " - %s (#%s)\n" "$(tput setaf 1)${groupname}$(tput sgr0)" "$(getent group ${groupname} | cut -d: -f3)"
			elif [ "${groupname}" = "$(whoami)" ]; then
				printf " - %s (#%s)\n" "$(tput setaf 6)${groupname}$(tput sgr0)" "$(getent group ${groupname} | cut -d: -f3)"
			else
				printf " - %s (#%s)\n" "${groupname}" "$(getent group ${groupname} | cut -d: -f3)"
			fi
		else
			printf " - %s (#%s)\n" "${groupname}" "$(getent group ${groupname} | cut -d: -f3)"
		fi
	done
else
	aprintf "Member of group(s)" "$(groups)"
fi

aprintf "Home directory" "${HOME}"

exit 0

Dit script produceert een lijst met systeeminformatie in de volgende groepen: