Hello, The attached patch adds support for the -m (--machine) option to provide machine-readable output. It uses a different format than the one described in this bug report because I implemented it before I found this bug report, but I'm open to suggestions to change it.
Regards Simon -- + privacy is necessary + using gnupg http://gnupg.org + public key id: 0x92FEFDB7E44C32F9
diff -Nru debian-goodies-0.63/checkrestart debian-goodies-0.63simon1/checkrestart
--- debian-goodies-0.63/checkrestart 2013-07-05 14:37:50.000000000 +0200
+++ debian-goodies-0.63simon1/checkrestart 2014-08-31 23:11:24.000000000 +0200
@@ -59,7 +59,7 @@
return 1
def usage():
- sys.stderr.write('usage: checkrestart [-vhpa] [-bblacklist] [-iignore]\n')
+ sys.stderr.write('usage: checkrestart [-vhpam] [-bblacklist] [-iignore]\n')
def main():
global lc_all_c_env, file_query_check
@@ -75,7 +75,7 @@
# Process options
try:
- opts, args = getopt.getopt(sys.argv[1:], "hvpab:i:", ["help", "verbose", "packages", "all", "blacklist", "ignore"])
+ opts, args = getopt.getopt(sys.argv[1:], "hvpamb:i:", ["help", "verbose", "packages", "all", "machine", "blacklist", "ignore"])
except getopt.GetoptError, err:
# print help information and exit:
print str(err) # will print something like "option -x not recognized"
@@ -89,6 +89,8 @@
onlyPackageFiles = False
# Look for any deleted file
allFiles = False
+ # Generate machine parsable output
+ machineOutput = False
for o, a in opts:
if o in ("-v", "--verbose"):
@@ -101,6 +103,8 @@
elif o in ("-a", "--all"):
allFiles = True
onlyPackageFiles = False
+ elif o in ("-m", "--machine"):
+ machineOutput = True
elif o in ("-b", "--blacklist"):
blacklistFiles.append(a)
onlyPackageFiles = False
@@ -130,7 +134,8 @@
toRestart = lsofcheck(blacklist = blacklist)
- print "Found %d processes using old versions of upgraded files" % len(toRestart)
+ if not machineOutput:
+ print "Found %d processes using old versions of upgraded files" % len(toRestart)
if len(toRestart) == 0:
sys.exit(0)
@@ -140,16 +145,20 @@
programs.setdefault(process.program, [])
programs[process.program].append(process)
- if len(programs) == 1:
- print "(%d distinct program)" % len(programs)
- else:
- print "(%d distinct programs)" % len(programs)
+ if not machineOutput:
+ if len(programs) == 1:
+ print "(%d distinct program)" % len(programs)
+ else:
+ print "(%d distinct programs)" % len(programs)
# Verbose information
if verbose:
for process in toRestart:
- print "Process %s (PID: %d) " % (process.program, process.pid)
- process.listDeleted()
+ if not machineOutput:
+ print "Process %s (PID: %d) " % (process.program, process.pid)
+ process.listDeleted()
+ else:
+ process.listDeletedMachine()
packages = {}
diverted = None
@@ -157,13 +166,13 @@
dpkgQuery = ["dpkg-query", "--search"] + programs.keys()
dpkgProc = subprocess.Popen(dpkgQuery, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env = lc_all_c_env)
- if verbose:
+ if verbose and not machineOutput:
print "Running:%s" % dpkgQuery
while True:
line = dpkgProc.stdout.readline()
if not line:
break
- if verbose:
+ if verbose and not machineOutput:
print "Reading line: %s" % line
if line.startswith('local diversion'):
continue
@@ -195,11 +204,13 @@
# Close the pipe
dpkgProc.stdout.close()
- print "(%d distinct packages)" % len(packages)
+ if not machineOutput:
+ print "(%d distinct packages)" % len(packages)
if len(packages) == 0:
- print "No packages seem to need to be restarted."
- print "(please read checkrestart(1))"
+ if not machineOutput:
+ print "No packages seem to need to be restarted."
+ print "(please read checkrestart(1))"
sys.exit(0)
for package in packages.values():
@@ -243,25 +254,31 @@
nonrestartable.append(package)
if len(restartable) > 0:
- print
- print "Of these, %d seem to contain init scripts which can be used to restart them:" % len(restartable)
- # TODO - consider putting this in a --verbose option
- print "The following packages seem to have init scripts that could be used\nto restart them:"
- for package in restartable:
- print package.name + ':'
- for process in package.processes:
- print "\t%s\t%s" % (process.pid,process.program)
-
- print
- print "These are the init scripts:"
- print '\n'.join(restartCommands)
- print
+ if not machineOutput:
+ print
+ print "Of these, %d seem to contain init scripts which can be used to restart them:" % len(restartable)
+ # TODO - consider putting this in a --verbose option
+ print "The following packages seem to have init scripts that could be used\nto restart them:"
+ for package in restartable:
+ print package.name + ':'
+ for process in package.processes:
+ print "\t%s\t%s" % (process.pid,process.program)
+
+ print
+ print "These are the init scripts:"
+ print '\n'.join(restartCommands)
+ print
+ else:
+ for package in restartable:
+ for process in package.processes:
+ print 'init\t%s\t%s\t%s' % (package.name,process.pid,process.program)
if len(nonrestartable) == 0:
sys.exit(0)
# TODO - consider putting this in a --verbose option
- print "These processes do not seem to have an associated init script to restart them:"
+ if not machineOutput:
+ print "These processes do not seem to have an associated init script to restart them:"
for package in nonrestartable:
skip = False
if ignorelist:
@@ -270,9 +287,13 @@
skip = True
if skip:
continue
- print package.name + ':'
- for process in package.processes:
- print "\t%s\t%s" % (process.pid,process.program)
+ if not machineOutput:
+ print package.name + ':'
+ for process in package.processes:
+ print "\t%s\t%s" % (process.pid,process.program)
+ else:
+ for process in package.processes:
+ print 'no-init\t%s\t%s\t%s' % (package.name,process.pid,process.program)
def lsofcheck(blacklist = None):
processes = {}
@@ -600,16 +621,22 @@
# print "Changing usr to " + newusr + " result:" +f; # Debugging
return re.sub('( \(deleted\)|.dpkg-new).*$','',f)
- def listDeleted(self):
+ def listDeletedHelper(self):
listfiles = []
- listdescriptors = []
for f in self.files:
if isdeletedFile(f):
listfiles.append(f)
- if listfiles != []:
+ return listfiles
+ def listDeleted(self):
+ listfiles = self.listDeletedHelper()
+ if listfiles != []:
print "List of deleted files in use:"
for file in listfiles:
print "\t" + file
+ def listDeletedMachine(self):
+ listfiles = self.listDeletedHelper()
+ for file in listfiles:
+ print 'file\t%s\t%s\t%s' % (self.pid, self.program, file)
# Check if a process needs to be restarted, previously we would
# just check if it used libraries named '.dpkg-new' since that's
diff -Nru debian-goodies-0.63/checkrestart.1 debian-goodies-0.63simon1/checkrestart.1
--- debian-goodies-0.63/checkrestart.1 2013-07-05 13:47:13.000000000 +0200
+++ debian-goodies-0.63simon1/checkrestart.1 2014-08-31 23:19:26.000000000 +0200
@@ -6,7 +6,7 @@
.SH NAME
checkrestart \- check which processes need to be restarted after an upgrade
.SH SYNOPSIS
-.B checkrestart [ -hvpa ] [ -b blacklist_file ] [ -i package_name ]
+.B checkrestart [ -hvpam ] [ -b blacklist_file ] [ -i package_name ]
.SH DESCRIPTION
The
.B checkrestart
@@ -58,6 +58,13 @@
option.
.TP
+.BI -m, --machine
+Generate machine readable output. One line is printed per program which must
+restarted: "<type>\\t<package>\\t<pid>\\t<program>". <type> is "init", if an
+init script is available to restart the program, "no-init" otherwise (without
+the quotes).
+
+.TP
.BI -b\ file, --blacklist=file
Read a blacklist of regular expressions from
.I file.
@@ -128,6 +135,14 @@
isc-dhcp-client:
3775 /sbin/dhclient
+This is another example to show the machine-readable output:
+
+ # checkrestart --machine
+ init bcfg2-server 6974 /usr/sbin/bcfg2-server
+ init exim4-daemon-light 857 /usr/sbin/exim4
+ no-init aptitude 11679 /usr/bin/aptitude-curses
+ no-init xscreensaver 6562 /usr/bin/xscreensaver
+
.SH BUGS
This program might fail if the output of the \fIlsof\fP utility changes since it
depends on it to detect which deleted files are used by processes. It might
signature.asc
Description: Digital signature

