У меня много домашних каталогов в / ifshome в Linux. Я хочу увидеть, какие пользователи не входили в систему в течение последних 6 месяцев, и мое решение - проанализировать файл /ifshome/user/.lastlogin. Каждый файл .lastlogin имеет одинаковый формат, 1 строка:
Last Login: Fri Mar 09 18:06:27 PST 2001
Мне нужно создать сценарий оболочки, который может анализировать файл .lastlogin в домашнем каталоге каждого пользователя и выводить те каталоги, владельцы которых не входили в систему в течение последних 6 месяцев.





Правильно ли я предполагаю, что последнее время должно более или менее совпадать со временем изменения файла? Если это так, вы можете легко использовать команду find, чтобы найти файлы новее, чем шесть месяцев назад.
Удаление этих файлов из «исходного» списка приведет к появлению более старых.
Откуда берется файл .lastlogin? Это стандарт Linux, потому что у меня его нет?
Я только что нашел в своей системе команду lastlog, которая может дать вам информацию обо всех, кто последний раз входил в систему определенное количество дней назад:
-b, --before DAYS
Print only lastlog records older than DAYS.
Я бы не стал предполагать, что он находится в домашнем каталоге пользователей (было бы довольно небезопасно полагаться на пользователя. Они могли бы легко изменить файл). так что меня не удивит, если у вас нет ~ / .lastlog. но кто знает, так ли это для него, на его месте я бы действительно это изменил :)
.lastlogin кажется башизмом. Если вы используете любую другую оболочку, ее там не будет. Итак, да, первоначальная идея оставляет желать лучшего.
Хорошо, в чистом сценарии оболочки вы, вероятно, захотите использовать sort (1) с пустым значением в качестве sep поля. что-то вроде
$ find /ifshome/user/ -name .lastlogin -print |
xargs sort --key=8,8 --key=4,4 --key=5,5
(предупреждение, непроверено.)
Возможно, вам будет проще использовать python или perl, так как они лучше подходят для обработки даты.
Разве при этом не теряются имена файлов - а значит, и имена пользователей?
хорошо, я понятия не имел, что sort можно использовать для сортировки по месяцам. однако я бы не стал использовать find. он будет рекурсивно перемещаться по подкаталогам - вам это не нужно. почему бы не сортировать --key = 8,8 --key = 4,4 --key = 5,5 /ifshome/*/.lastlogin?
ДЛ: Ну вот почему это «что-то вроде». Надо оставить что-нибудь в качестве упражнения для ученика. litb: Я не был уверен, что он всегда будет находиться в самом верхнем каталоге. Если это так, то мы эквивалентны, может быть, на скошь быстрее. Также ключу нужен флаг, чтобы правильно отсортировать месяцы.
Вы можете найти команду 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.
Смотрите ниже мою версию, если ваш код, некоторые незначительные изменения в соответствии с моими потребностями. Спасибо!
Предупреждение: это может сделать только дата GNU, поэтому результат может зависеть от используемого вами Unix (да, OQ был помечен как linux, но ничто не заставляет систему на основе Linux использовать дату GNU).
Вот некоторые незначительные изменения в коде литб. Это может занять # месяцев в качестве параметра, и он выводит строго имя пользователя, за которым следуют месяцы с момента изменения:
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 месяцам).
Наличие или отсутствие файла .lastlogin зависит от вашей оболочки. Не все снаряды это делают.