用于比较Linux中多个文件的日期的Shell脚本

时间:2008-12-30 20:04:08

标签: linux datetime shell

我在Linux上的/ ifshome下有很多主目录。我想查看哪些用户在过去6个月内没有登录,我的解决方案是解析/ifshome/user/.lastlogin文件。每个.lastlogin文件都具有相同的格式,1行:

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

我需要构建一个shell脚本,它可以解析每个用户主目录中的.lastlogin文件,并输出其所有者在过去6个月内未登录的目录。

8 个答案:

答案 0 :(得分:4)

您可能会发现last命令对您有所帮助。它将列出登录的最后N个用户,或在特定时间登录的用户等。man page

答案 1 :(得分:3)

好的,在纯shell脚本中,您可能希望将sort(1)与blank一起用作字段sep。

之类的东西
$ find /ifshome/user/ -name .lastlogin -print |
  xargs sort --key=8,8 --key=4,4 --key=5,5 

(警告,未经测试。)

你可能会发现使用python或perl更容易,因为它们有更好的日期处理选择。

答案 2 :(得分:1)

我是否正确假设最新时间应该或多或少等于文件的更改时间?如果是这样,您可以轻松使用find命令查找比六个月前更新的文件。

从“原始”列表中删除这些文件会产生较旧的文件。

答案 3 :(得分:1)

好的,这是我愚蠢的方式(未经测试!)使用纯shell脚本解析您的文件。

date命令可以解析日期字符串,并输出自1970年以来的秒数。从当前秒数中减去它们,然后除以一个月所需的秒数。将该值与用户路径一起打印。

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 -n对输出进行排序,并将其输入less,然后您可以浏览用户及其活动列表。

对于非hackish方式,请考虑Juan的最后日志。它也在我的linux上。

答案 4 :(得分:1)

在我看来,该文件的内容可能会回显文件的修改时间戳,因此您可以使用更简单的命令:

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

打印所有名为.lastlogin的文件,修改时间超过182天(选择您自己的近似值为6个月)。

答案 5 :(得分:0)

.lastlogin文件来自哪里?这是一个linux标准,因为我没有吗?

我刚刚在我的系统上找到了“lastlog”命令,该命令可以为您提供最后一次登录指定天数的所有人:

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

答案 6 :(得分:0)

使用以下代码可以相对轻松地在PERL中完成:

#!/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";
    }
  }
}

答案 7 :(得分:0)

以下是对 litb 代码的一些细微更改。它可能需要#months作为参数,并且它会严格输出用户名,然后输入自更改后的月份:

<强> 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