Quick-and-dirty "need reboot" script.
There are much more advanced options already existing, but I wanted it the most KISS as possible.
It's also tolerably fast.
Only standard tools used: bash, date, uname, file, grep, sed, awk, paste, column, and /proc files.
No attempt at restarting services, not even mapping processes to service names.
Not well tested, likely to miss something and crap out in some cases, standard disclaimer applies.
Intended to run with sudo else only user processes are listed.
Can be called from command line or sourced for the functions.
Reports running and installed kernel versions, last update to /boot, running updated binaries.
reboot_test.sh
#!/bin/bash
last_chboot() { date -r /boot +%s; }
last_chboot_hr() { date -r /boot +'%F %T'; }
last_reboot() { date -r /proc +%s; }
last_reboot_hr() { date -r /proc +'%F %T'; }
upgraded_boot() (( $(last_chboot) > $(last_reboot) ))
upgraded_boot_hr() { upgraded_boot && echo yes || echo no; }
currently_booted_image() { grep -Po 'BOOT_IMAGE=/@\K\S+' /proc/cmdline; }
currently_running_kernel() { uname -r; }
currently_installed_kernel() { file $(currently_booted_image) |grep -Po 'version \K\S+'; }
currently_installed_kernels() { file /boot/vmlinuz* |grep -Po 'version \K\S+' |paste -sd' '; }
upgraded_running_kernel() { [ $(currently_running_kernel) != $(currently_installed_kernel) ]; }
upgraded_running_kernel_hr() { upgraded_running_kernel && echo yes || echo no; }
# NOTE: $1=pid $6=pathname $7="(deleted)"
awk_uniq_del_paths_simple() { # unused, no command / user name, only pathname and list of pids
awk '$6 && $7 {pathpids[$6]=(pathpids[$6] " " $1)} END { for (pp in pathpids) print pp " " pathpids[pp] }';
}
awk_uniq_del_paths() {
awk ' $6 && $7 {pathpids[$6][$1]=""}
END {
for (path in pathpids) for (pid in pathpids[path]) {
getline uid < ("/proc/" pid "/loginuid")
("id -nu " uid) | getline user
getline comm < ("/proc/" pid "/comm")
print pid " " comm " " uid " " user " " path
}
}
'
}
upgraded_mapped_executables() {
trap "$(shopt -p nullglob)" RETURN; shopt -s nullglob
local p
for p in /proc/{1..9}*; do
sed -En '/^\S+ +..x. .*[^]]$/ {s/^\S+/'"${p:6}"'/;p}' "$p/maps" 2>&-
done |awk_uniq_del_paths
}
upgraded_mapped_executables_hr() {
echo # just to simplify printing function names and results
upgraded_mapped_executables |column -t -N'pid,comm,uid,user,path' -R1,3
}
return 0 2>&- # exit if sourced
for fn in currently_{booted_image,running_kernel,installed_kernel{,s}} last_{ch,re}boot_hr upgraded_{boot,running_kernel,mapped_executables}_hr; do
printf '%-32s : ' "$fn"; $fn
done
example output
(I reinstalled mpg123 and rebuilt initramfs)
currently_booted_image : /boot/vmlinuz-linux-zen
currently_running_kernel : 6.2.10-zen1-1-zen
currently_installed_kernel : 6.2.10-zen1-1-zen
currently_installed_kernels : 6.2.10-zen1-1-zen
last_chboot_hr : 2023-04-13 16:41:59
last_reboot_hr : 2023-04-12 22:13:36
upgraded_boot_hr : yes
upgraded_running_kernel_hr : no
upgraded_mapped_executables_hr :
pid comm uid user path
907 waybar 1000 meanruse /usr/lib/libmpg123.so.0.47.0
27794 firedragon 1000 meanruse /usr/lib/libmpg123.so.0.47.0
________________________________________________________
Executed in 1.77 secs fish external
usr time 1.11 secs 0.75 millis 1.11 secs
sys time 0.69 secs 3.02 millis 0.69 secs
May do as a quick reminder, beware it's far from being dependable.