Skript pro výpis uživatelů v nočních hodinách

tomo19

Skript pro výpis uživatelů v nočních hodinách
« kdy: 24. 10. 2010, 05:45:39 »
dostal som zaulohu naprogramovat skript, v ktorom vypisem za pomoci prikazu last, zoznam uzivatelov ktory sa do systemu hlasia v nocnych hodinach, tj.: v case medzi 22:00 a 05:00, format vypisi je uzivatel, pocet prihlaseni, a pocet posledneho NOCNEHO(cize datumovo najnovsieho) prihlasenia do systemu, rata sa iba s ukoncenymi relaciami...musim to byt shell(csh alebo bash), nie perl
...riesim to na freebsd

....trapim sa s tym v bashi uz cele tri dni po sebe, pri 10000 riadkovom vystupe z last mi ten skript bezi 7 minut aj viac uz naozaj neviem ako to mam dalej optimalizovat

...vie mi neikto poradit ako nato efektivne? ak je to nevyhnutne tak aj za pouzitia (g)awk

-------------------------------------------------------------------------------------------------
moj postup, zatial mam iba toto ale uz teraz skript trva velmi dlho:

zoznam1 = last -> vygrepujem vsetky ukoncene spojenia, vynecam usera reboot a posledne dva riadky vo vystupe last(prazdny a wtmp begins...), odstranim prebytocne medzerty, vyjmem potrebne stlpce

zoznam2 = last -> ustriedeny zoznam uzivatelov zo zoznam1, kazdy user iba jedenkra

pre kazdeho usera za zoznam2 rob toto:
-- vygrepuj vsetky zaznam zo zoznam1 pre daneho usera, dostanem tak zoznam casovo usporiadany z last prikazu, najprv najnovsie prihlasenie potom najstarsie
-- vsetky ich prejdem riadok po riadku a osetrim riadky na ktorych chyba nazov hosta, tj.: indexi stlpcov su tam posunute
-- cas v tvare "hod:min" trnsformujem na cislo "hodmin", bez bodkociarky

==> tu nastava problem, v cykle for, prikaz

cas_cislo=`echo "$cas_retazec" | tr -d ':'`

privelmi spomaluje skript pre 10000 zaznamov, z 4min. skriptu sa tymto riadkom stava 7 min. skript

-- porovnam s casom aktualneho riadka, ak je to nocne prihlasenie tak to vypisem na terminal
« Poslední změna: 24. 10. 2010, 11:08:34 od Petr Krčmář »


deadmail

Re: last a uzivatelia v nocnych hodinach (hlavne freebsd)
« Odpověď #1 kdy: 24. 10. 2010, 06:16:26 »
A co tak nocne prihlasenie vygrepovat podla hodiny?

Nieco ako
Kód: [Vybrat]
0[0-6]|2[2-4] pre dvojcifernu hodinu.

uni

Re: last a uzivatelia v nocnych hodinach (hlavne freebsd)
« Odpověď #2 kdy: 24. 10. 2010, 06:51:36 »
pre kazdeho usera za zoznam2 rob toto:
-- vygrepuj vsetky zaznam zo zoznam1 pre daneho usera, dostanem tak zoznam casovo usporiadany z last prikazu, najprv najnovsie prihlasenie potom najstarsie

ked by si sa rozhodol pre awk (odporucam mawk, casto je radovo rychlejsi nez gawk a je slusne kompatibilny), tak mas k dispozicii asociativne polia a mozes ten zoznam1 prejst na jeden priechod a robit si statistiku ku kazdemu uzivatelovi priebezne.

ak nie, tak zrejme bude rychlejsie (log zaznamov je predpokladam menej nez mas uzivatelov) urobit namiesto prveho zoznamu jeho ekvivalent, ktory vsak prezenies sortom na usera (tj. nech su userove zaznamy zgrupene pri sebe) & spracovat linearne takto vytvoreny zoznam - treba si rucne osetrit "prepnutie" na dalsieho uzivatela & robit si k nemu statistiku...

tomo19

Re: last a uzivatelia v nocnych hodinach (hlavne freebsd)
« Odpověď #3 kdy: 24. 10. 2010, 13:04:20 »
A co tak nocne prihlasenie vygrepovat podla hodiny?

Nieco ako
Kód: [Vybrat]
0[0-6]|2[2-4] pre dvojcifernu hodinu.

to sa bohuzial neda, kedze sa vysktuju riadky kde chyba nazov servera z ktore sa user prihlasil a namiesto nazbu su tam iba medzery, skratka - v taktom to riadku je o jeden stlpec menej, potom v kolonke cas by bola pmlcka

Re: Skript pro výpis uživatelů v nočních hodinách
« Odpověď #4 kdy: 24. 10. 2010, 22:12:26 »
Hmm.. neviem ako je to vo FreeBSD, ale v linuxe ma last formatovany vystup - t.j. hodnoty stlpcov v riadku zacinaju na specifickych poziciach. Takze som zbuchal nieco taketo(v linuxe funguje OK) - prg_awk:

BEGIN {
        c=0;
}

substr($0,10,13)~/^pts|tty/ && substr($0,51,13)~/^(2[23]|0[1234]):[0-9][0-9] \- [0-9][0-9]:[0-9][0-9]$/ {
        n=substr($0,0,8);
        if(n in nh) {
                nh[n]++;
        } else {
                na[c++]=n;
                nh[n]=1;
                a[n]=substr($0,40)
        }
}

END {
        for (j=0;j<c;j++) {
                print na[j]"|"nh[na[j]]"|"a[na[j]];     
        }
}



...a teda potom vystup moze vyzerat takto:


$ last | awk -f prg_awk
webmaste|3|Sun Oct 24 01:59 - 02:01  (00:01)   
root    |9|Fri Oct 22 23:15 - 23:42  (00:27)   
zzzzz   |2|Thu Oct 14 22:23 - 22:23  (00:00)   
yyyy    |3|Thu Oct 14 02:06 - 02:08  (00:02)   
xxx     |1|Wed Oct 13 22:18 - 22:35  (00:17)   
$



PS: hmmm vsimol som si, ze mi odtial pomizli indexi poli - \[i\] --> ktore editor tu pouziva na nastavovanie italic pisma.. uz je to opravene na [j] :-\
« Poslední změna: 25. 10. 2010, 00:31:46 od NeoV »


dustin

Re: Skript pro výpis uživatelů v nočních hodinách
« Odpověď #5 kdy: 25. 10. 2010, 11:38:42 »
Nevím, jaký je důvod toho zadání. Může jít o školní příklad, pak je to jedno. Ale pokud má vzniknout dlouhodobě funkční řešení, pak by mi přišlo poněkud nešťastné muset parsovat výstup last, který se může někdy změnit, ale použil bych řešení rovnou navázané na tu definici utmp.h v libc (jednoduchý prográmek v C), nebo nějaké standardní knihovny (např. utmp v perlu), u kterých bych očekával, že budou do budoucna  odrážet případné změny definice utmp.h.