代码之家  ›  专栏  ›  技术社区  ›  DV.

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

  •  1
  • DV.  · 技术社区  · 16 年前

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

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

    8 回复  |  直到 15 年前
        1
  •  4
  •   rmeador    16 年前

    你可以找到 last 命令对你有帮助。它将列出最近登录的N个用户,或在特定时间登录的用户,等等。 man page

        2
  •  3
  •   Jonathan Leffler    16 年前

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

    (警告,未经测试。)

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

        3
  •  1
  •   xtofl Adam Rosenfield    16 年前

    我是否正确地假设最近的时间应该或多或少地等于文件的更改时间?如果是这样,您可以轻松地使用 find

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

        4
  •  1
  •   Johannes Schaub - litb    16 年前

    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 然后,您可以浏览用户及其活动的列表。

        5
  •  1
  •   Jonathan Leffler    16 年前

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

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

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

        6
  •  0
  •   Juan Juan    16 年前

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

           -b, --before DAYS
               Print only lastlog records older than DAYS.
    
    
        7
  •  0
  •   Jamie    16 年前

    #!/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";
        }
      }
    }
    
        8
  •  0
  •   DV.    16 年前

    这里有一些小的变化 的代码。它可以使用#个月作为参数,并严格输出用户名,后跟更改后的月份:

    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