Выбор строк по времени с auth.log

Искусство написания bash скриптов. Делимся своими наработками
Ответить
fenix85
Сообщения: 3
Зарегистрирован: 03 дек 2013, 09:29
Темы: 1
Статус: Не в сети

Выбор строк по времени с auth.log

Сообщение fenix85 » 03 дек 2013, 09:43

У меня такая проблема - нужно из файла /var/log/auth.log выбрать все строки записаны туда за последние 3 дня.
я не понимаю как это можно сделать с помощью date. помогите кто нибудь!

Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Re: выбор строк по времени с auth.log

Сообщение ZEN » 03 дек 2013, 11:38

Как-то вот так:

Код: Выделить всё

#!/usr/bin/env bash
LOG_FILE="/var/log/auth.log";
DAYS_FROM=3;

export LC_ALL="C";

UNIX_TIMESTAMP=$(date "+%s");
MIN_DAY=$(($UNIX_TIMESTAMP-86400*$DAYS_FROM));

if [[ ! -e $LOG_FILE ]]
then
    echo "$LOG_FILE not found" 2>&1;
    exit 1;
fi

while read LINE
do
    CUR_DAY=$(echo $LINE | awk '{print $1" "$2}' | xargs -I{} date -d "{}" "+%s");
    if [[ $CUR_DAY > $MIN_DAY ]]
    then
        echo $LINE;
    fi
done < <(cat $LOG_FILE)

exit 0;
В переменной DAYS_FROM указывается число сколько дней из лога вытащить. Так что при желании можно быстро поправить на другое число. Теоретически все это можно было бы решить только одним awk, но это я возможно буду сомтреть вечером, если данное решение по каким-то причинам не устроит. Да, кстати, если планируешь использовать в терминале данный код, то логичнее это все обернуть в функцию и закинуть в ~/.bashrc

Пока что поэксперементируй подойдет ли этот вариант. Быстро скачать скрипт можно командой из терминала:
wget -q "http://dumpz.org/746234/nixtext/" -O auth_parser.sh ; chmod +x auth_parser.sh

запускать скрипт вот так:
./auth_parser.sh
или вот так
bash auth_parser.sh
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

fenix85
Сообщения: 3
Зарегистрирован: 03 дек 2013, 09:29
Темы: 1
Статус: Не в сети

Re: выбор строк по времени с auth.log

Сообщение fenix85 » 03 дек 2013, 14:39

1)-объясните пожалуйста почему то умножение на 86400 и почему знак * не надо экранировать слэшем \* --MIN_DAY=$(($UNIX_TIMESTAMP - 86400*$DAYS_FROM));
2)-я пробовал использовать такую ​​запись времени три дня назад в секунадх DAYS_FROM_DAYS_AGO=$(date -d "3 days ago" "+%s") вместо 86400*$DAYS_FROM но оно ничего не дало мне, программа просто ничего не выводила ..???

3) - объясните пожалуйста подробно что происходит в строке когда строка времени передается на вход команде xargs -I{} date -d "{}" "+%s"

Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Re: выбор строк по времени с auth.log

Сообщение ZEN » 03 дек 2013, 17:18

fenix85 писал(а):1)-объясните пожалуйста почему то умножение на 86400 и почему знак * не надо экранировать слэшем \* --MIN_DAY=$(($UNIX_TIMESTAMP - 86400*$DAYS_FROM));
Вся фишка в двойных круглых скобках $(( )). баш воспринимает их как математическую операцию. Если бы скобки были одинарные $(), то их содержимое баш попытался бы вполнить как команду в сабшелле и в место вызова был бы подставлен результат работы команды. (как пример TEST=$(ls *) ; echo $TEST )
Что касается 86400 - это 24 часа в секундах (60*60*24).
fenix85 писал(а):2)-я пробовал использовать такую ​​запись времени три дня назад в секунадх DAYS_FROM_DAYS_AGO=$(date -d "3 days ago" "+%s") вместо 86400*$DAYS_FROM но оно ничего не дало мне, программа просто ничего не выводила ..???
Возможно в блоке if не поменяли имя переменной? Только что проверил, такой вариант:

Код: Выделить всё

#!/usr/bin/env bash
LOG_FILE="/var/log/auth.log";
MIN_DAY=$(date -d "3 days ago" "+%s");

if [[ ! -e $LOG_FILE ]]
then
    echo "$LOG_FILE not found" 2>&1;
    exit 1;
fi

while read LINE
do
    CUR_DAY=$(echo $LINE | awk '{print $1" "$2}' | xargs -I{} date -d "{}" "+%s");
    if [[ $CUR_DAY > $MIN_DAY ]]
    then
        echo $LINE;
    fi
done < <(cat $LOG_FILE)

exit 0;
вполне рабочий
fenix85 писал(а):3) - объясните пожалуйста подробно что происходит в строке когда строка времени передается на вход команде xargs -I{} date -d "{}" "+%s"
Здесь тоже особо сложного ничего нет. С помощью флага -I мы указываем xargs какое уникальное слово подменять тем, что было полученно ранее через пайп. Например, ранее у нас awk вытаскивал "Dec 1" и передавал чере pipe в xargs. xargs в свою очередь берет строку:

date -d "{}" "+%s"

находит символы {} и заменяет тем, что было получено через пайп. То есть "Dec 1":

date -d "Dec 1" "+%s"

и конечно же выполняет её. Получим 1385848800 в unix timestamp. Для проверки преобразуем её в читаемый вид

date -d @1385848800
Вс. дек. 1 00:00:00 EET 2013

То есть программа date распарсила день и число, а для всех остальных параметров использовала параметры по умолчанию.

Рекомендую для отадки скрипта использовать в bash параметр -x
bash -x auth_parser.sh
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

fenix85
Сообщения: 3
Зарегистрирован: 03 дек 2013, 09:29
Темы: 1
Статус: Не в сети

Re: выбор строк по времени с auth.log

Сообщение fenix85 » 03 дек 2013, 20:22

Спасибо! Для меня программирование в bash это что-то новенькое). Мне надо было вывести уникальных пользователей и количество их сессий за последние три дня. Вот как я это сделал) Правда с тем циклом и функцией read медленно работает но работае. Можете подсказать какую-то хорошую книгу по программированию в Linux sell (bash) на русский язык???

Код: Выделить всё

#!/bin/bash
LOG_FILE="/var/log/auth.log";
DAYS_FROM=3;
UNIX_TIMESTAMP=$(date +%s);
MIN_DAY=$(($UNIX_TIMESTAMP - 24*60*60*$DAYS_FROM));
while read LINE
do
    CUR_DAY=$(echo $LINE | awk '{print $1,$2,$3}' | xargs -I{} date -d "{}" +%s);
    if [[ $CUR_DAY > $MIN_DAY ]]
    then
        echo "$LINE" >> file_bufer;
    fi
done < <(cat $LOG_FILE | grep "opened for user" |awk '{print $1,$2,$3,$11}') 
 
 m_arrey=(`cat "file_bufer" | awk '{print $4}' | sort -u `)
i=0
while [ $i -lt ${#m_arrey[@]} ]
do
   echo ${m_arrey[i]} `grep -c ${m_arrey[i]} file_bufer`
   i=`expr $i + 1`
done
rm file_bufer

Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Re: выбор строк по времени с auth.log

Сообщение ZEN » 03 дек 2013, 21:56

Собственно, кроме Advanced Bash-Scripting Guide даже не знаю что порекомендовать... Довольно таки полный учебник по bash. Для разнообразия рекомендую обращать внимания на другие языки. Обычно те или иные подходы к программирования в разных языках вырабатывают в мозгу алгоритмы как лучше решить ту или иную задачу. Ну а в случае с bash, вполне не плохо обучаться путем автоматизации рутинных задач скриптами. В добавок не стесняться делиться наработками и не бояться критики. Код можно улучшать до бесконечности, так что любые хорошие идеи должны приветствоваться
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Re: Выбор строк по времени с auth.log

Сообщение ZEN » 12 ноя 2015, 13:38

Некропост, но тем не менее... Есть такая утилита - tac. В отличии от cat она печатает содержимое файла в обратную сторону. В результате появился немного оптимизированный вариант скрипта:

Код: Выделить всё

#!/usr/bin/env bash
LOG_FILE="/var/log/auth.log";
MIN_DAY=$(date -d "3 days ago" "+%s");

test -r "$LOG_FILE" || {
    echo "$LOG_FILE not found" 1>&2;
    exit 1;
}

BUFFER=();
while read LINE
do
    CUR_DAY=$(echo $LINE | awk '{print $1" "$2}' | xargs -I{} date -d "{}" "+%s");
    test "$CUR_DAY" -gt "$MIN_DAY" && BUFFER+=("$LINE");
done < <(tac $LOG_FILE);

printf "%s\n" "${BUFFER[@]}" | tac;

exit 0;
Суть в том, что мы построчно читаем файл с конца. И если дата в начале строки попадает в указанный промежуток времени, то мы её сохраняем в массив BUFFER. И так как строки у нас накапливаются так же в обратном порядке, то в строке с printf мы так же используем tac что бы развернуть текст обратно.
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей