arch-needs-restart/arch-needs-restart.sh

43 lines
1018 B
Bash
Raw Normal View History

2023-03-19 21:35:59 +01:00
#!/bin/bash
get_boot_kernel() {
local get_version=0
for field in $(file /boot/vmlinuz*); do
if [[ $get_version -eq 1 ]]; then
echo $field
return
elif [[ $field == version ]]; then
# the next field contains the version
get_version=1
fi
done
}
rc=1
libs=$(lsof -n +c 0 2> /dev/null | grep 'DEL.*lib' | awk '1 { print $1 ": " $NF }' | sort -u)
if [[ -n $libs ]]; then
cat <<< $libs
echo "# LIBS: reboot required"
rc=0
fi
fix(script): Trigger restart only on FDs for binaries (#3) Rename variable and its echo output headline to something that implies we're talking about binaries specifically, not all files. Also add an awk condition that only outputs an lsof line if lsof showed a file descriptor to a path somewhere in a /bin/ or /sbin/ directory. As a good enough approximation this will help us trigger a system reboot when something in /usr/bin/foo or /usr/local/sbin/bar was deleted while at the same time vastly reducing the amount of unnecessary system reboots for random /memfd anonymous files and shared memory objects in /dev/shm. An awk program has multiple repetitions of 'condition { action }' where the action is literally written inside curly braces. Replace the pseudo-condition '1' (i.e. something that is always truthy) with '$(NF-1) ~ /\/s?bin\//'. To break it down the new condition is: - If the second to last field in a line ... $(NF-1) - Matches an expression ... $(NF-1) ~ /expression/ - That is /s?bin/ ... /s?bin/ Then we want to do '{ action }' which will still print affected file descriptors as before. An awk expression is encapsulated in a slash pair like so: '/expression/'. We want to search for any string that contains literal slashes like so: '/s?bin/'. We unfortunately have to escape the slashes we want to find to make sure awk doesn't treat them as the end of its awk expression string: +------+------ Backslash-escape here v v - Right: $(NF-1) ~ /\/s?bin\// - Wrong: $(NF-1) ~ //s?bin// The expression 's?' is probably self-explanatory. An awk expression is related to a regular expression but not identical to it. Still, a question mark means the same thing as in a PERL-compatible regular expression, the preceding character is optional: we want either one of '/sbin/' or '/bin/'.
2024-06-19 20:16:37 +02:00
binaries=$(lsof -n +c 0 2> /dev/null | grep -- '(deleted)' | awk '$(NF-1) ~ /\/s?bin\// { print $1 ": " $(NF-1) " " $NF }' | sort -u)
if [[ -n $binaries ]]; then
cat <<< $binaries
echo "# BINARIES: reboot required"
rc=0
fi
2023-03-19 21:35:59 +01:00
active_kernel=$(uname -r)
current_kernel=$(get_boot_kernel)
if [[ $active_kernel != $current_kernel ]]; then
echo "$active_kernel < $current_kernel"
echo "# KERNEL: reboot required"
rc=0
fi
if [[ $rc == '1' ]]; then
echo "# No reboot required"
fi