-
Notifications
You must be signed in to change notification settings - Fork 10
/
wcheckrestart
executable file
·105 lines (96 loc) · 3.28 KB
/
wcheckrestart
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
#!/bin/sh
# wcheckrestart (part of ossobv/vcutil) // wdoekes/2014,2018,2020
# // Public Domain
#
# Checks which services need to be restarted after an upgrade. Inspired
# by:
# - checkrestart (from debian-goodies), a more complicated version of this
# - https://locallost.net/?p=233
# - http://askubuntu.com/questions/194/how-can-i-install-just-\
# security-updates-from-the-command-line
#
# Usage:
#
# sudo wcheckrestart [-v] [options_to_ps]
# sudo wcheckrestart -vv
# sudo wcheckrestart -sd | sudo xargs systemctl restart
#
# Examples:
#
# # Check which processes need a restart and restart them.
# sudo wcheckrestart
# sudo /etc/init.d/this-and-that restart # :)
#
# # Check which PIDs still have an old libssl loaded.
# sudo wcheckrestart -vv | grep libssl
#
# # Pass options 'h' and '-o pid' to 'ps', to get the PIDs only.
# sudo wcheckrestart -v h -o pid # | awk NF=NF RS= OFS=,
#
verbose=0
options_to_ps=f
if test "$*" = "-sd"; then
verbose=-1
elif test "$*" = "-vv"; then
verbose=2
elif test "$1" = "-v"; then
verbose=1
shift
fi
if test -n "$*"; then
options_to_ps="$@"
fi
if test $(whoami) != root; then
echo "must be root" 2>/dev/null
exit 1
fi
shown=""
toshow=""
# Create a regex of PIDs '^ *123 |^ *456 ' based on all processes that have
# "(deleted)" so files, according to /proc/PID/maps.
# (Some java processes create a temporary dynamic library as /tmp/*.so
# and delete it after load. We exclude those.)
pids=$(find /proc -maxdepth 2 -name maps -path '/proc/[0-9]*/maps' \
2>/dev/null |
xargs grep -E '\.so(\..*)? \(deleted\)$' /dev/null 2>/dev/null |
grep -v '[[:blank:]]/tmp/' |
sed -e 's#/proc/\([0-9]*\)/.*$#^ *\1 #' | uniq | tr '\n' '|' |
sed -e 's/|$//')
test -z "$pids" && exit 0
# call `ps fhax` to get sane sorting (parents first)
for pids in $(ps fhax -opid,ppid | grep -E "$pids" |
sed -e 's/^ *//;s/ *$//;s/ \+/,/'); do
pid=${pids%,*}
ppid=${pids#*,}
shown="$shown $pid "
exe=$(readlink /proc/$pid/exe 2>/dev/null) || continue
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=777691
# Ignore dbus; right now it cannot be restarted without rebooting the
# system. Don't tempt the user to try and find a way.
test "$exe" = "/usr/bin/dbus-daemon" && continue
test "$exe" = "/usr/bin/dbus-daemon (deleted)" && continue
# If not verbose, and parentpid is not 1 (in case we've already
# shown /sbin/init) and we've already added the parent, then
# don't show it.
test $verbose -le 0 && test $ppid != 1 &&
test "$shown" != "${shown% $ppid *}" &&
continue
toshow="$toshow,$pid"
if test $verbose -ge 2; then
cmdline=$(tr '\0' ' ' </proc/$pid/cmdline)
echo "PID $pid $cmdline"
grep -E '\.so(\..*)? \(deleted\)$' /proc/$pid/maps 2>/dev/null |
sed -e "s/^/ $pid /"
echo
fi
done
if test -n "$toshow"; then
if test $verbose -eq -1; then
# "* some.service - Some Service"
LC_ALL=C systemctl status $(echo "$toshow" | sed -e 's/^.//;s/,/ /g') |
sed '/^[*] .* - .*/!d;s/^[^ ] //;s/ - .*//;/[.]scope$/d' | sort -u
elif test $verbose -le 1; then
ps $options_to_ps -p $(echo "$toshow" | sed -e 's/^.//')
fi
fi
# vim: set ts=8 sw=4 sts=4 et: