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