-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcheck_reboot.sh
More file actions
executable file
·195 lines (172 loc) · 5.79 KB
/
check_reboot.sh
File metadata and controls
executable file
·195 lines (172 loc) · 5.79 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
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
#!/bin/sh
########################################################################
# check_reboot.sh: Reboot Requirement Check Tool
#
# Description:
# This script checks whether a system reboot is required after updates.
# It uses two independent signals and reports results with consistent
# log levels:
#
# 1) /var/run/reboot-required (Debian/Ubuntu mechanism)
# - If present, a reboot is requested by packaging hooks.
# - If /var/run/reboot-required.pkgs exists, it lists trigger packages.
#
# 2) needrestart (process-based mechanism, optional)
# - Detects running processes that still use old binaries/libraries
# after upgrades and determines whether a reboot is required.
# - This check is executed only when needrestart is installed and
# the script runs as root (recommended for accurate inspection).
#
# Author: id774 (More info: http://id774.net)
# Source Code: https://github.com/id774/scripts
# License: The GPL version 3, or LGPL version 3 (Dual License).
# Contact: idnanashi@gmail.com
#
# Design Notes:
# - The script is POSIX sh compatible.
# - It is safe to run on non-Debian systems; reboot-required files may
# not exist, and needrestart may be unavailable. In that case it will
# only report what it can determine.
# - "Reboot required" is a logical OR:
# reboot_required_file || needrestart_requires_reboot
#
# Usage:
# ./check_reboot.sh [options]
#
# Options:
# -h, --help: Show this help and exit.
# -v, --version: Show this help and exit (unified behavior).
#
# Error Conditions:
# 0: Success (check completed; see logs for reboot requirement)
# 1: General Failure
# 126: Command exists but is not executable
# 127: Command not found
#
# Examples:
# ./check_reboot.sh
#
# Version History:
# v1.0 2026-01-24
# Initial release.
#
########################################################################
# Display full script header information extracted from the top comment block
usage() {
awk '
BEGIN { in_header = 0 }
/^#{10,}$/ { if (!in_header) { in_header = 1; next } else exit }
in_header && /^# ?/ { print substr($0, 3) }
' "$0"
exit 0
}
# Check if the system is Linux
check_system() {
if [ "$(uname -s 2>/dev/null)" != "Linux" ]; then
echo "[ERROR] This script is intended for Linux systems only." >&2
exit 1
fi
}
# Check if required commands are available and executable
check_commands() {
for cmd in "$@"; do
cmd_path=$(command -v "$cmd" 2>/dev/null)
if [ -z "$cmd_path" ]; then
echo "[ERROR] Command '$cmd' is not installed. Please install $cmd and try again." >&2
exit 127
elif [ ! -x "$cmd_path" ]; then
echo "[ERROR] Command '$cmd' is not executable. Please check the permissions." >&2
exit 126
fi
done
}
# Check whether a command exists in PATH
have_command() {
command -v "$1" >/dev/null 2>&1
}
# Determine whether the current user is root
is_root() {
# Prefer id -u (portable). If id is missing, check_commands covers it.
[ "$(id -u 2>/dev/null)" = "0" ]
}
# Check Debian/Ubuntu reboot-required marker files
check_reboot_required_files() {
reboot_flag="/var/run/reboot-required"
pkgs_file="/var/run/reboot-required.pkgs"
# When this file exists, Debian/Ubuntu considers a reboot to be required.
if [ -f "$reboot_flag" ]; then
echo "[WARN] Reboot required: $reboot_flag exists"
# The optional .pkgs file contains one package name per line.
# It may be absent depending on the environment and hooks.
if [ -f "$pkgs_file" ]; then
echo "[INFO] Reboot-required packages:"
# Prefix for consistent log format.
sed 's/^/[INFO] - /' "$pkgs_file"
else
echo "[INFO] Package list not available: $pkgs_file not found"
fi
return 0
fi
echo "[INFO] No reboot-required flag: $reboot_flag not found"
return 1
}
# Check reboot requirement using needrestart (if available)
check_needrestart() {
# needrestart is optional; skip if not installed.
if ! have_command needrestart; then
echo "[INFO] needrestart not installed; skipping needrestart check"
return 2
fi
# needrestart typically needs root for accurate process inspection.
# Running unprivileged may lead to incomplete results.
if ! is_root; then
echo "[WARN] needrestart found but not running as root; skipping needrestart check"
return 2
fi
# Non-interactive and reboot-only check:
# -r l : check reboot requirement (return 0=no reboot, 1=reboot required)
# -b : batch mode (avoid interactive prompts)
echo "[INFO] Running needrestart (batch, reboot-only)"
needrestart -r l -b >/dev/null 2>&1
rc=$?
case "$rc" in
0)
echo "[INFO] needrestart: reboot not required"
return 1
;;
1)
echo "[WARN] needrestart: reboot required"
return 0
;;
*)
echo "[ERROR] needrestart returned unexpected status: $rc" >&2
return 3
;;
esac
}
# Main entry point of the script
main() {
case "$1" in
-h|--help|-v|--version) usage ;;
esac
check_system
check_commands awk sed id uname
# Track whether any method indicates a reboot requirement.
reboot_required=0
# Method 1: reboot-required marker files
if check_reboot_required_files; then
reboot_required=1
fi
# Method 2: needrestart (optional)
check_needrestart
nr_res=$?
[ "$nr_res" -eq 0 ] && reboot_required=1
if [ "$reboot_required" -eq 1 ]; then
echo "[WARN] Reboot is required"
else
echo "[INFO] Reboot is not required"
fi
return 0
}
# Execute main function
main "$@"