Shell script to compare dates from multiple files in Linux

I have many home directories under / ifshome on Linux. I want to find out which users have not logged in in the last 6 months and my solution is to parse the /ifshome/user/.lastlogin file. Each .lastlogin file has the same format, 1 line:

Last Login: Fri Mar 09 18:06:27 PST 2001

      

I need to create a wrapper script that can parse the .lastlogin file in each user's home directory and list those directories that have not been logged in in the last 6 months.

+1


source to share


8 answers


Ok, here's my silly way (untested!) Using a clean shell script, parsing your file.

The command date

can parse a date string and output seconds since 1970. Subtract them from the current seconds and divide by the number of seconds, which takes one month. Print this value along with the custom path.

for i in /ifshome/*/.lastlogin; do
    dates=$(cat $i | grep "Last Login:" | cut -d: -f 2-)
    if [ ! -z "$dates" ]; then
      months=$(( ($(date +%s) - $(date -d "$dates" +%s)) / (60*60*24*31) ))
      echo $months $i
    fi
done

      



Sort the result with sort -n

and move it to less

, then you can view the list of users and their activity.

For an uncommon way, consider Juan's bad debt idea. This is also on my Linux.

+1


source


You may find a command last

that is useful to you. It will list the last N users who have logged in, or users registered at a specific time, etc. reference page



+4


source


Okay, in a clean shell script, you probably want to use sort (1) with a space as the sep field. something like

$ find /ifshome/user/ -name .lastlogin -print |
  xargs sort --key=8,8 --key=4,4 --key=5,5 

      

(warning, untested.)

You might find it easier to use python or perl as they have better options for handling date.

+3


source


Can we assume that the last time should be more or less equal to the file modification time? If so, you can easily use the command find

to find files newer than six months ago.

Removing these files from the "original" list will result in older ones.

+1


source


It seems to me that the contents of the file are likely to echo the file's modified timestamp, so you can use a much simpler command:

 find /ifshome -name .lastlogin -mtime +182 -print

      

Print all files named .lastlogin with modification times within 182 days (choose your own approximation to 6 months).

+1


source


Where did the .lastlogin file come from? Is this a linux standard because I don't have one?

I just found a "lastlog" command on my system that can give you everyone who last logged in on a given number of days ago:

       -b, --before DAYS
           Print only lastlog records older than DAYS.

0


source


This can be done relatively easily in PERL with the following code:

#!/usr/bin/perl

use strict;
use Time::Local ();

my $dir = "/ifshome";

my $month = {
  'Jan' => 0, 'Feb' => 1, 'Mar' => 2, 'Apr' => 3, 'May' => 4, 'Jun' => 5,
  'Jul' => 6, 'Aug' => 7, 'Sep' => 8, 'Oct' => 9, 'Nov' => 10, 'Dec' => 11,
};

my $expire = time() - (86400 * 30 * 6);

foreach my $home (<$dir/*>) {
  open(F,"$home/.lastlogin");
  chomp(my $line = <F>);

  if ($line =~ /^Last Login:\s+\w{3}\s+(\w{3})\s+(\d{2})\s+(\d{2}):(\d{2}):(\d{2})\s+\w+\s+(\d{4})/) {
    my $ts = Time::Local::timelocal($5,$4,$3,$2,$month->{$1},$6-1900);
    if ($ts < $expire) {
      my($user) = (split(/\//,$home))[-1];
      print "$user account is expired\n";
    }
  }
}

      

0


source


Here are some minor changes to the litb code. This can take several months as a parameter, and it outputs the strictly username followed by months since they were changed:

oldusers.sh:

echo "Purpose: Parse /ifshome and find dates in .lastlogin files that are older than MONTHS months."
echo "Usage: ./oldusers.sh [MONTHS=6]"
echo ""

case $# in
1)
monthmin=$1
;;
*)
monthmin=6
;;
esac

if [ "${monthmin//[^0-9]/}" != $monthmin ]; then echo "$monthmin is NaN";
else
 for i in ./*/.lastlogin; do
    dates=$(cat $i | grep "Last Login:" | cut -d: -f 2-)
    if [ ! -z "$dates" ]; then
      months=$(( ($(date +%s) - $(date -d "$dates" +%s)) / (60*60*24*30) ))
      user=$(echo $i | cut -d/ -f 2- | cut -d/ -f -1)
      if test $months -ge $monthmin; then echo "$user: $months months ago"; fi
    fi
 done
fi

      

0


source







All Articles