ubuntuusers.de

awk Befehl in Variable speichern

Status: Ungelöst | Ubuntu-Version: Ubuntu 16.10 (Yakkety Yak)
Antworten |

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

argonsputter schrieb:

Der Zeitvergleich ist noch etwas zu hoch für mich. ...

Ich verstehe nicht ganz -
Bei mir gibt last doch die Zeitsummen bereits mit aus:

track@track:~$ last  |  grep "^track   tty7"
track   tty7         :0               Thu Jan 12 10:36   still logged in   
track   tty7         :0               Wed Jan 11 10:58 - down   (11:57)    
track   tty7         :0               Tue Jan 10 09:06 - down   (10:30)    
track   tty7         :0               Mon Jan  9 12:59 - down   (10:08)    
track   tty7         :0               Mon Jan  9 09:12 - down   (03:29)    
track   tty7         :0               Sat Jan  7 10:50 - down   (11:08)     

... oder sieht das bei Dir anders aus ?

Denn daraus ginge ja die Zeitsumme recht einfach zu berechnen: (ok, ich nehme für sowas aus alter Gewohnheit awk )

track@track:~$ last  |  awk  '/^track   tty7/ { print; split($NF,t,"[(:)]"); h+=t[2]; m+=t[3] }
                                          END { print "Zeitsumme:\t" h+int(m/60) ":" m%60 }'
track   tty7         :0               Thu Jan 12 10:36   still logged in   
track   tty7         :0               Wed Jan 11 10:58 - down   (11:57)    
track   tty7         :0               Tue Jan 10 09:06 - down   (10:30)    
track   tty7         :0               Mon Jan  9 12:59 - down   (10:08)    
track   tty7         :0               Mon Jan  9 09:12 - down   (03:29)    
track   tty7         :0               Sat Jan  7 10:50 - down   (11:08)    
Zeitsumme:	47:12 

Wozu willst Du da das Zeitlogging noch selber zu Fuß nachbauen ...?!

LG,

track

argonsputter

(Themenstarter)

Anmeldungsdatum:
15. April 2016

Beiträge: 17

track schrieb:

Denn daraus ginge ja die Zeitsumme recht einfach zu berechnen: (ok, ich nehme für sowas aus alter Gewohnheit awk )

track@track:~$ last  |  awk  '/^track   tty7/ { print; split($NF,t,"[(:)]"); h+=t[2]; m+=t[3] }
                                          END { print "Zeitsumme:\t" h+int(m/60) ":" m%60 }'
track   tty7         :0               Thu Jan 12 10:36   still logged in   
track   tty7         :0               Wed Jan 11 10:58 - down   (11:57)    
track   tty7         :0               Tue Jan 10 09:06 - down   (10:30)    
track   tty7         :0               Mon Jan  9 12:59 - down   (10:08)    
track   tty7         :0               Mon Jan  9 09:12 - down   (03:29)    
track   tty7         :0               Sat Jan  7 10:50 - down   (11:08)    
Zeitsumme:	47:12 

Wozu willst Du da das Zeitlogging noch selber zu Fuß nachbauen ...?!

Weil die Zeitrechnung durch die Überlappung nicht stimmt. In deinem Beispiel:

track tty7 :0 Mon Jan 9 12:59 - down (10:08) track tty7 :0 Mon Jan 9 09:12 - down (03:29)

Hier wird ab 12:59 bis zum "down" doppelt gezählt. Ich wollte die Zeiten in den Klammern addieren, aber wenn der Benutzer mehrere Terminals offen hat, dann komme ich locker auf über >24h pro Tag.

curly schrieb:

Hier ebenfalls zwei interessante Ansätze:

http://www.linuxquestions.org/questions/linux-newbie-8/total-login-time-of-each-user-in-last-940715/

http://www.ihaveapc.com/2011/03/how-to-find-out-total-log-in-time-of-users-in-linux-mint-ubuntu/

Witzig, genau diese beide Seiten hatte ich vorhin auch noch gefunden. Das Perl script läuft, aber auch hier wird doppelt gezählt. Interessant, dass dies niemanden stört.

Nochmal zur Verdeutlichung:

1
2
argon       pts/3        Fri Jan 13 00:08 - 00:12  (00:04)     
argon       pts/2        Fri Jan 13 00:07 - 00:13  (00:05)     

Zusammengezählt sind es dann 9Min, dabei beträgt meine eigentliche effektive Zeit doch nur 6 Minuten!

Ich denke, ich werde dies acct / psacct testen oder halt ein eigenes Logging erstellen. (/etc/profile & /etc/.bash_logout )

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

argonsputter schrieb:

track   tty7         :0               Mon Jan  9 12:59 - down   (10:08)    
track   tty7         :0               Mon Jan  9 09:12 - down   (03:29)

Hier wird ab 12:59 bis zum "down" doppelt gezählt.

Nee, wird es nicht. Denn

  1. gibt es die Konsole tty7 nur ein Mal. Also kann sie nicht doppelt gezählt werden. Und

  2. tatsächlich: das "down" war schon um 12:41 - wenn Du es mal nachrechnest.

Also von daher hat das schon Hand und Fuß, wenn Du tatsächlich nach Konsole tty7 (das ist die grafische Konsole !) filtern kannst.
Natürlich: dann und nur dann klappt das so einfach.

Wenn verschiedene Konsolen im Spiel sind, musst Du aber auch bei Deiner Selbstbau-Lösung noch so einiges nachfiltern.
Z.B: wie willst Du da mitloggen, wenn das System heruntergefahren wird (oder abschmiert), ohne dass sich jemand ausloggt ?

Ansonsten: bau Deinen Ansatz doch einfach mal, probier ihn aus und zeig was 'rauskommt.
Im schlimmsten Fall hättest eben Du "nur" eine gute Programmier-Übung gehabt ...

LG,

track

argonsputter

(Themenstarter)

Anmeldungsdatum:
15. April 2016

Beiträge: 17

track schrieb:

  1. gibt es die Konsole tty7 nur ein Mal. Also kann sie nicht doppelt gezählt werden. Und

Genau das ist es ja.. sind mehrere Konsolen im Spiel, dann habe ich eine Überlappung ☺

Z.B: wie willst Du da mitloggen, wenn das System heruntergefahren wird (oder abschmiert), ohne dass sich jemand ausloggt ?

  • Beim Login (/etc/profile) wird eine Datei (/tmp/whoami_Timestamp) erstellt mit dem Inhalt Login.timestamp

  • Öffnet der Benutzer eine zweite Session, müsste doch nochmal die /etc/profile geladen werden. Dort würde ich vorher überprüfen, ob es schon eine /tmp/whoami_Timestamp existiert

  • Falls ja, alles so lassen.

  • Loggt sich der Benutzer aus, schaue ich mit who, ob noch eine weitere Session mit seinem Benutzernamen läuft.

  • Falls ja, alles so lassen.

  • Falls nicht, neuer Eintrag Logout.timestamp

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Ok, das heißt: Du filterst die mehrfachen Logins bereits auf der Logging-Ebene. Das erspart Dir in der Tat späteres Basteln.

Was passiert, wenn jemand das System herunterfährt, also bei einem sudo halt oder sudo reboot ? - dann fehlt ja der 2. Zeitstempel.
Kann das praktisch nicht vorkommen, oder wäre das egal ?

Denn das gibt last ja auch aus, wenn auch ohne Zeitstempel.

track

argonsputter

(Themenstarter)

Anmeldungsdatum:
15. April 2016

Beiträge: 17

track schrieb:

Was passiert, wenn jemand das System herunterfährt, also bei einem sudo halt oder sudo reboot ? - dann fehlt ja der 2. Zeitstempel.

Ich wollte dies mit einem Service verwirklichen, der bei Runlevel 0 1 6 checkt, ob noch "offene" Logfiles vorhanden sind. Ich habe gestern noch mit ~/.bash_logout experiementiert. Das sah ganz gut aus. Ein /etc/.bash_logout ging global leider nicht. Um jetzt nicht jedem User ein .bash_logout ins Home zu packen, könnte ich in der /etc/.bashrc eine If Abfrage erstellen, ob die ~/bash_logout schon existiert und falls nicht - erstellen. ☺

Wirklich komisch, dass die Zeitangabe so konfus ist. Selbst mit der Application "acc" bekomme ich z.B. für den 12. Januar auf meinem System die totale Zeit von 32h angezeigt. Dabei hatte ich mehrere ssh Sessions und war lokal auch noch angemeldet.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Für mich klingt das so, als wenn Du gerade das Rad noch einmal erfindest.

Aus dem Grunde würde ich auf jeden Fall für ein Auswerten von last -F [name] plädieren, weil man dann nur noch die "down"- Zeitstempel selber errechnen muss.
Dabei kommen die Ausgaben ja bereits schön der Reihe nach sortiert nach Login-Zeit an, die neueste zuerst. Das heißt, wenn man sie rückwärts durchgeht: solange die nächste Login-Zeit vor der Logout-Zeit liegt, ist es noch der selbe Login-Block. Also von der Logik her nicht so schlimm.

Die Zeitstempel umwandeln geht an sich ja auch, denn das kann das Shell- date wunderwunderschön alleine:

track@track:~$ date -d " Wed Jan  4 12:30:59 2017"
Mi 4. Jan 12:30:59 CET 2017
track@track:~$ date -d " Wed Jan  4 12:30:59 2017" +%s
1483529459
track@track:~$ last -F track  |  awk -F "[-()]" '{ 
    $0=substr($0,38); sub("   "," - "); "date +%s -d \"" $1 "\" 2> /dev/null" | getline t1; print $0, t1;  }'
  Fri Jan 13 14:23:33 2017 - still logged in                       1484313813
  Fri Jan 13 12:17:43 2017 - still logged in                       1484306263
  Fri Jan 13 00:22:15 2017 - Fri Jan 13 00:23:52 2017  (00:01) -   1484263335
  Thu Jan 12 23:38:37 2017 - Thu Jan 12 23:44:58 2017  (00:06) -   1484260717
  Thu Jan 12 22:36:21 2017 - Thu Jan 12 23:36:56 2017  (01:00) -   1484256981
  Thu Jan 12 19:22:32 2017 - Thu Jan 12 22:35:37 2017  (03:13) -   1484245352
  Thu Jan 12 13:45:41 2017 - Thu Jan 12 13:46:12 2017  (00:00) -   1484225141 

Du siehst, wie man bei awk den Shell-Befehl einbinden kann. Und schon hast Du den Zeitstempel in Sekunden, ohne viel Aufwand ...

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13207

track schrieb:

Für mich klingt das so, als wenn Du gerade das Rad noch einmal erfindest.

Aus dem Grunde würde ich auf jeden Fall für ein Auswerten von last -F [name] plädieren, weil man dann nur noch die "down"- Zeitstempel selber errechnen muss.

👍

Ist auch effizienter, als zusätzliche Dinge bei jedem Login zu machen.

argonsputter

(Themenstarter)

Anmeldungsdatum:
15. April 2016

Beiträge: 17

track schrieb:

Für mich klingt das so, als wenn Du gerade das Rad noch einmal erfindest.

Aus dem Grunde würde ich auf jeden Fall für ein Auswerten von last -F [name] plädieren, weil man dann nur noch die "down"- Zeitstempel selber errechnen muss.
Dabei kommen die Ausgaben ja bereits schön der Reihe nach sortiert nach Login-Zeit an, die neueste zuerst. Das heißt, wenn man sie rückwärts durchgeht: solange die nächste Login-Zeit vor der Logout-Zeit liegt, ist es noch der selbe Login-Block. Also von der Logik her nicht so schlimm.

Die Zeitstempel umwandeln geht an sich ja auch, denn das kann das Shell- date wunderwunderschön alleine...

Wow! Also sagst du auch, ich solle lieber mit Last arbeiten und wie rklm zu Anfang meinte, die Zeiten zu vergleichen.

Danke für die Hilfestellung. Ich werde jetzt erstmal dein awk Befehl zerlegen und verstehen 😉

argonsputter

(Themenstarter)

Anmeldungsdatum:
15. April 2016

Beiträge: 17

Leider bekomme ich die Sekunden nicht ausgegeben.

Fehler

1
2
 last -F argon  |  awk -F "[-()]" '{ $0=substr($0,38); sub("   "," - "); "date +%s -d \"" $1 "\" 2> /dev/null" | getline t1; print $0, t1;  }'
/bin/sh: 1: Syntax error: Unterminated quoted string

Ich muss aber zugeben, dass ich dies gerade auf meinem Raspberry teste. Aber in der Hilfe von awk lese ich schon "The getline command is used in several different ways and should not be used by beginners." 😉

Sehe ich das richtig, dass du mit -() nach den Zeichen suchst, dann ab den Ersten bis 38. Zeichen dir schnappst, den Tab und den Bindestrich als Koordinate, dann die Sekundenangabe über date holst und einfach nur ranhängst?

Ich prüfe gerade, ob die einzelnen Module hier klappen. Dazu gehören:

  1. Eingeloggte Benutzer am Tag identifizieren und speichern

2. Diese Auflistung Schritt für Schritt auf Überlappungen überprüfen

ich habe mir soweit schonmal dies gebastelt: (für Debugzwecke hole ich mir nur die letzten 10 Logins)

1
2
3
4
5
6
#!/bin/bash

while read line
do
        echo "Hier die IF Abfrage, ob es Überlappungen gibt"
done < <(last -dawn 10 |awk '{print $1}'|sort|uniq)

Bin aber ehrlich gesagt immer noch unsicher, welche Methode ich hier machen soll. Mit last zu arbeiten setzt mehr Verständnis mit awk voraus. Bei der anderen Idee mit dem eigenen Logging über ~/.bash_profile fühle ich mich sicherer, weil ich da so ungefähr weiss, was ich tue 😉 Allerdings ist Track's Idee mit den Sekunden auch gut. Denn da könnte ich ja auch die Startzeit in Sekunden umwandeln und dann fällt es mir leichter Überlappungen zu erkennen. arrrrrrr... ☹

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

argonsputter schrieb:

Fehler

1
2
 last -F argon  |  awk -F "[-()]" '{ $0=substr($0,38); sub("   "," - "); "date +%s -d \"" $1 "\" 2> /dev/null" | getline t1; print $0, t1;  }'
/bin/sh: 1: Syntax error: Unterminated quoted string

Auf welche mysteriöse Art hast Du den Befehl denn eingegeben ? - so direkt auf der Konsole kann ja wohl nicht sein, denn die Zeile ist ja korrekt "gequotet".

Ich muss aber zugeben, dass ich dies gerade auf meinem Raspberry teste. Aber in der Hilfe von awk lese ich schon "The getline command is used in several different ways and should not be used by beginners." 😉

Shell ist hier Shell, das ist das Problem nicht. Und ja: solche einen Shellbefehl einzubinden hat so seine Tücken, vor allem weil Du dabei 3 Ebenen "Quoting" brauchst. Deshalb habe ich Dir den Befehl ja auch fix und fertig (und getestet !) angeliefert.

Ansonsten führe mal vor der Befehlszeile ein set -x aus, und kopiere dann die Meldungen vollständig hier in einen Codeblock.

LG,

track

Antworten |