Сценарий оболочки для сравнения дат из нескольких файлов в Linux

У меня много домашних каталогов в / ifshome в Linux. Я хочу увидеть, какие пользователи не входили в систему в течение последних 6 месяцев, и мое решение - проанализировать файл /ifshome/user/.lastlogin. Каждый файл .lastlogin имеет одинаковый формат, 1 строка:

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

Мне нужно создать сценарий оболочки, который может анализировать файл .lastlogin в домашнем каталоге каждого пользователя и выводить те каталоги, владельцы которых не входили в систему в течение последних 6 месяцев.

Наличие или отсутствие файла .lastlogin зависит от вашей оболочки. Не все снаряды это делают.

bortzmeyer 05.01.2009 15:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
9 447
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Правильно ли я предполагаю, что последнее время должно более или менее совпадать со временем изменения файла? Если это так, вы можете легко использовать команду find, чтобы найти файлы новее, чем шесть месяцев назад.

Удаление этих файлов из «исходного» списка приведет к появлению более старых.

Откуда берется файл .lastlogin? Это стандарт Linux, потому что у меня его нет?

Я только что нашел в своей системе команду lastlog, которая может дать вам информацию обо всех, кто последний раз входил в систему определенное количество дней назад:

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

Я бы не стал предполагать, что он находится в домашнем каталоге пользователей (было бы довольно небезопасно полагаться на пользователя. Они могли бы легко изменить файл). так что меня не удивит, если у вас нет ~ / .lastlog. но кто знает, так ли это для него, на его месте я бы действительно это изменил :)

Johannes Schaub - litb 30.12.2008 23:47

.lastlogin кажется башизмом. Если вы используете любую другую оболочку, ее там не будет. Итак, да, первоначальная идея оставляет желать лучшего.

bortzmeyer 05.01.2009 15:21

Хорошо, в чистом сценарии оболочки вы, вероятно, захотите использовать sort (1) с пустым значением в качестве sep поля. что-то вроде

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

(предупреждение, непроверено.)

Возможно, вам будет проще использовать python или perl, так как они лучше подходят для обработки даты.

Разве при этом не теряются имена файлов - а значит, и имена пользователей?

Jonathan Leffler 30.12.2008 23:47

хорошо, я понятия не имел, что sort можно использовать для сортировки по месяцам. однако я бы не стал использовать find. он будет рекурсивно перемещаться по подкаталогам - вам это не нужно. почему бы не сортировать --key = 8,8 --key = 4,4 --key = 5,5 /ifshome/*/.lastlogin?

Johannes Schaub - litb 31.12.2008 00:13

ДЛ: Ну вот почему это «что-то вроде». Надо оставить что-нибудь в качестве упражнения для ученика. litb: Я не был уверен, что он всегда будет находиться в самом верхнем каталоге. Если это так, то мы эквивалентны, может быть, на скошь быстрее. Также ключу нужен флаг, чтобы правильно отсортировать месяцы.

Charlie Martin 31.12.2008 02:36

Вы можете найти команду last полезной для вас. В нем будут перечислены последние N пользователей, которые вошли в систему, или пользователи, вошедшие в систему в определенное время, и т. д. страница руководства

Это можно сделать относительно легко в 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";
    }
  }
}
Ответ принят как подходящий

Хорошо, вот мой глупый способ (непроверенный!) С использованием чистого сценария оболочки, анализирующего ваш файл.

Команда 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, после чего вы сможете просмотреть список пользователей и их активность.

В качестве нехакерского пути рассмотрим идею Хуана о последнем журнале. Это тоже на моем Linux.

Смотрите ниже мою версию, если ваш код, некоторые незначительные изменения в соответствии с моими потребностями. Спасибо!

DV. 31.12.2008 00:43

Предупреждение: это может сделать только дата GNU, поэтому результат может зависеть от используемого вами Unix (да, OQ был помечен как linux, но ничто не заставляет систему на основе Linux использовать дату GNU).

bortzmeyer 05.01.2009 15:20

Вот некоторые незначительные изменения в коде литб. Это может занять # месяцев в качестве параметра, и он выводит строго имя пользователя, за которым следуют месяцы с момента изменения:

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

Мне кажется, что содержимое файла, скорее всего, будет отражать метку времени модификации файла, поэтому вы можете использовать гораздо более простую команду:

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

Распечатайте все файлы с именем .lastlogin со сроком модификации более 182 дней (выберите собственное приближение к 6 месяцам).

Другие вопросы по теме