bash: testing whether anyone is or has recently been logged in?
Adam Funk
a24061 at ducksburg.com
Thu Jul 7 05:47:50 EDT 2011
On 2011-04-20, Bill Marcum wrote:
> On 2011-04-20, Adam Funk <a24061 at ducksburg.com> wrote:
>> I'd appreciate any suggestions for testing (preferably from a bash
>> script, although perl or python would be OK too) whether anyone is
>> currently logged in, and whether anyone has been logged in during the
>> past $N minutes.
>>
>> (The idea is to use this in a cron script that only does its job when
>> the machine is not "in live use".)
>>
> A script could parse the output of "who", "w" or "last", and the stored
> output from previous commands.
[adding comp.lang.python]
Here's what I came up with in python. If you call it with no
arguments or with 0 as the argument, it gives a 0 exit code if no-one
is logged in. If you call it with a non-zero argument N, it gives a 0
exit code if no-one has been logged in in the past N minutes.
I welcome suggestions, corrections, &c.
#v+
#!/usr/bin/python
# -*- coding: utf-8 -*-
import subprocess, re
from dateutil.parser import *
from sys import stdout, stderr, argv
from datetime import datetime, timedelta
from optparse import OptionParser
oparser = OptionParser(usage="usage: %prog [options] [N]")
oparser.add_option("-v", dest="verbose", default=False, action="store_true",
help="Verbose output")
(options, args) = oparser.parse_args()
query = 0
try:
if len(args) > 0:
query = int(args[0])
except ValueError:
stderr.write('Invalid argument %s\n' % argv[1])
exit(-1)
if (options.verbose):
stdout.write('query %i\n' % query)
last_proc = subprocess.Popen(args=['last'], stdout=subprocess.PIPE)
last_out = last_proc.stdout.read().split('\n')
still_logged = re.compile(r'still logged in')
line_pattern = re.compile(r'^\S+\s+\S+\s+\S+\s+(\S+\s+\S+\s+\S+) ..:.. - (..:..)\s+.*$')
timestamps = [];
minutes = 1
for line in last_out:
if line.startswith('reboot'):
pass
elif still_logged.search(line):
minutes = 0
if (options.verbose):
stdout.write('still logged in\n')
break
else:
matcher = line_pattern.match(line)
# user term host Tue Apr 26 13:49 - 14:52 (01:02)
if matcher:
date_string = matcher.group(1) + ' ' + matcher.group(2)
timestamp = parse(date_string)
stdout.write('d> ' + date_string + ' --> ' + str(timestamp) + '\n')
timestamps.append(timestamp)
if len(timestamps) > 0:
latest = max(timestamps)
stderr.write(str(latest) + '\n')
now = datetime.now()
delta = now - latest
minutes = delta.days * 24 * 60 + delta.seconds / 60
diff_value = query + 1 - minutes
exit_value = max (0, diff_value)
if (options.verbose):
stdout.write('min %i\n' % minutes)
stdout.write('diff %i\n' % diff_value)
stdout.write('exit %i\n' % exit_value)
exit(exit_value)
#v-
--
I worry that 10 or 15 years from now, [my daughter] will come to me
and say 'Daddy, where were you when they took freedom of the press
away from the Internet?' [Mike Godwin]
http://www.eff.org/
More information about the Python-list
mailing list