Ich versuche ein Shellscript zu schreiben was die gesamte Logginzeit eines Nutzers an einem Rechner ermittelt werden soll

Hinweis: In dem Thema Ich versuche ein Shellscript zu schreiben was die gesamte Logginzeit eines Nutzers an einem Rechner ermittelt werden soll gibt es 14 Antworten auf 2 Seiten. Der letzte Beitrag () befindet sich auf der letzten Seite.
  • Also ich danke euch schon mal für die Antworten =D :thumbsup: :thumbup:

    ich habe weiter dran gearbeitet, komme aber nicht zum Ergebnis.

    Also die wichtigen Informationen die ich vorenthalten habe sind wie folg.

    Das Skript soll als erstes den Rechnernamen und den Nutzernamen übernehmen
    also bsp.: ./logtime.sh MEINRECHNER MEINNAME
    also ist MEINRECHNER dann $1 und MEINNAME $2

    dann soll er prüfen ob der Rechner erreichbar ist und ob der Nutzer auf diesem Rechner existiert

    was ich ja mit ping und finger gemacht hatte. Wobei finger allein nicht ausreicht

    Quellcode

    1. ssh $1 finger $2




    sollte dafür gehen.

    Anschließend möchte ich also die gesamte Loginzeit des Nutzers ermittel die er insgesamt auf diesen rechner verbracht hat
    diese sind ja im /var/log/wtmp* verzeichnissen gespeichert
    Das heist ich muss die da irgendwie auswerten und und zusammenrechnen.

    Dazu lege ich einen temp. Ordner an, den ich auf die Variable TMP speichere

    Quellcode

    1. TMP=mktemp -d $(basename $0)-temp-created-$(date +%Y-%m-%d_%H:%M:%S)_XXXXXXXXX
    dann hole ich mir mittels scp den die wtmp Dateien und entpacke sie mittels unxz :smilie_pc_011:

    Quellcode

    1. scp $1:/var/log/wtmp* $TMP
    2. unxz $TMP/*.xz
    und jetzt komme ich an die Probleme. Wie kann ich jede wtmp Datei auswerten (also eine wtmp und mehrere bsp 14 auf dem Server wtmp-20170112).
    Dazu dachte ich

    Quellcode

    1. PFAD= $TMP/wtmp-[0-9]* # $TMP ist das TMP Verzeichnispfad
    2. while #Hier weiß ich noch nicht welche Bedingung ich reinschreibe
    3. do
    4. LOGIN=last -F -f $PFAD $1 | cut -c 50-58 # $1 ist der USER
    5. #ich müsste ja eine Laufvariable für LOGIN haben damit jeder Login eingespeichert wird
    6. done
    7. while
    8. do
    9. LOGOUT=last -F -f $PFAD $1 | cut -c 78-85
    10. done
    11. DATE=date +"%s"
    Alles anzeigen


    Hier habe ich das Problem das er das last Kommando nicht erkannt wird, also wird dieser auch Falsch sein


    wie kann ich das besser realisieren? ?( ?(

    Für den Inhalt des Beitrages 103583 haftet ausdrücklich der jeweilige Autor: Timmi0701

  • Shell-Script

    1. for this_file in /Pfad/wtmp* # die Bash expandiert alle Dateinamen
    2. do
    3. some_var=$( someCommand ) # schreibt Output von someCommand in som_var
    4. dosomething else
    5. user_array+=( $( command output some users) )
    6. done
    7. for looser in ${user_array[@]}; do
    8. echo user ist jetzt : $looser
    9. done
    Sokrates sagte, dass er nichts wisse.
    Ich bin viel, viel klüger als Sokrates.
    Ich weiß ganz genau, dass ich gar nichts weiß.

    Für den Inhalt des Beitrages 103592 haftet ausdrücklich der jeweilige Autor: Berichtigung

  • Was mir noch so einfällt:
    Du gehst ja eh mit ssh auf die Kiste. Also kannst du auch wirklich auf finger verzichten.
    Du müsstest den Output von finger ja auch erst filtern.
    Einfacher mag es sein für alle User einfach die Usernamen aus der /etc/passwd zu lesen.

    Shell-Script

    1. # alle User
    2. awk -F: '{if ($3>999 && $3 < 60000){ print $1}}' /etc/passwd
    3. # da die UserIDs auf anderen Distris/Unices erheblich von openSUSE
    4. # abweichen können, oder vom root anders gesetzt sein können,
    5. # könnte man auch die tatsächlich gültigen Werte für 999 und 60000
    6. # einfach lesen:
    7. grep UID_MIN /etc/login.defs
    8. grep UID_MAX /etc/login.defs
    Sokrates sagte, dass er nichts wisse.
    Ich bin viel, viel klüger als Sokrates.
    Ich weiß ganz genau, dass ich gar nichts weiß.

    Für den Inhalt des Beitrages 103606 haftet ausdrücklich der jeweilige Autor: Berichtigung

  • Halöchen, :D

    also so sieht mein derzeitiger Forschungsstand aus

    Quellcode

    1. for var in $TMP/wtmp*
    2. do
    3. LOGIN=$(last -F -f $var | grep $2 | cut -c 44-63)
    4. LOGOUT=$(last -F -f $var | grep $2 | cut -c 71-90)
    5. while read -r line
    6. do
    7. LITIME=$(date -d "$line" +%s)
    8. done <<< "$LOGIN"
    9. echo $LITIME
    10. while read -r line2
    11. do
    12. LOTIME=$(date -d "$line2" +%s)
    13. done <<< "$LOGOUT"
    14. echo $LOTIME
    15. let total${count}=$LOTIME-$LITIME
    16. echo "toal= $total$count" #Also bei der Variante kommt nichts gescheites raus
    17. echo "total= $total" #Hier kommt nichts (leeres Feld nach dem = )
    18. echo "total= $total${count}" #War ja klar dass das nicht Funktioniert
    19. #Zähler um eins erhöhen
    20. count=$((count + 1))
    21. done
    Alles anzeigen
    Mein Problem ist jetzt wie man sieht, die Variable total auzugeben. Also ich denke mal so wie ich das jetzt zusammengeschrieben habe, mit total${count} hoffe ich das er die variable um eins Zählt also das es eine total1, total2, ...,totaln gibt
    Wie gebe ich diese aber wieder aus :smilie_pc_011:

    Für den Inhalt des Beitrages 103753 haftet ausdrücklich der jeweilige Autor: Timmi0701

  • Shell-Script

    1. for var in $TMP/wtmp*
    2. do
    3. LOGIN=$(last -F -f $var | grep $2 | cut -c 44-63)
    4. LOGOUT=$(last -F -f $var | grep $2 | cut -c 71-90)
    Nimm für eigene Variablen keine durchgehende Großschreibung.

    Die ist eigentlich für Environmentvariablen und für reine Systemvariablen gedacht.
    Das ist schlechter Stil. Auch wenn im Internet noch so viele schlechte Beispiele dieser Unsitte folgen.
    Man kann damit leicht mal eine solche Variable versehentlich ändern. Die Resultate können verheerend sein.
    (Es gibt viel mehr solcher Variablen, als der gemeine Shellscripter kennt.)

    Die Logik mit der du diese verschachtelten Schleifen baust, ist schwer zu durchdringen.
    Guter Code ist von jedem Leser zu verstehen.
    Bei dir muss man ganz schön um die Ecke denken.
    Das ist später kaum mehr zu wartender Code. Den wird man lieber neu schreiben, als an veränderte Anforderungen anpassen zu wollen.
    Solche Sünden holen dich ein. Eher früher, als später.


    Shell-Script

    1. echo $LOTIME
    2. let total${count}=$LOTIME-$LITIME
    3. echo "toal= $total$count" #Also bei der Variante kommt nichts gescheites raus
    4. echo "total= $total" #Hier kommt nichts (leeres Feld nach dem = )
    5. echo "total= $total${count}" #War ja klar dass das nicht Funktioniert
    6. #Zähler um eins erhöhen
    7. count=$((count + 1))
    8. done
    Das Leerzeichen nach dem Istgleich ist nicht dein Problem. Innerhalb des Strings, den echo ausgibt, ist da halt ein Leerzeichen.
    count=$((count + 1)) lässt sich kürzer schreiben: ((count++)) genügt. Der Dollar vor dem runden Klammerpaar bewirkt die Expansion. Der Ausdruck wird also zum Wert der Addition expandiert, den du dann wieder der Variablen zuweist. Es genügt einfach die Variable hochzuzählen. Der Inkrementoperator tut das ohne viel Tippen auch alleine. Und ohne Expansion und erneute Zuweisung.

    Das ist ganz, ganz schlechter Stil, der sehr fehlerträchtig ist: let total${count}=$LOTIME-$LITIME
    Das let ist alte Posix Shell Syntax. Die bash ist moderner und kennt leistungsfähigere und elegantere Konstrukte.
    Da du Bashisms schreibst, muss es bash sein. Es macht also wenig Sinn auf die alte umständliche Syntax zurückzugreifen.
    Noch schlimmer ist es, alte Syntax mit moderner zu vermischen. ${...} ist moderne Syntax.

    Und dann ist da ein ganz kapitaler Fehler drin: Du denkst, dass du der Reihe nach verschiedene Variablen names total<Ziffer> setzt. Das passiert auch. Nur kannst du dann darauf nicht mehr zugreifen. Denn das Konstrukt echo "total= $total${count}" wird nur einmal ausgewertet. Beim Parsen ersetzt die Bash $total mit nichts, weil eben die Variable total nirgends gesetzt worden ist. Erinnere dich: Du hattest Variablen, wie total12 oder total5 gesetzt, aber eben nicht total. Und ${count} hat halt den Wert, den count gerade hat. Mehr wird nicht ausgegeben. Deine gesetzten total-Variablen bleiben unbeachtet.

    Es gibt auch nur einen Weg, das auf diese Art zu lösen. Den schreibe ich aber nicht, weil eval evil ist. Das nimmt man nur, wenn man wirklich gute Gründe UND keine, und wirklich keine andere Möglichkeit mehr hat.
    Die Bash kennt aber Arrays und sogar assoziative Arrays. Die sind hier gefragt.
    Eine Übersicht über Arrays findet sich hier.
    Noch eleganter und effizienter wären hier assoziative Arrays. Der User wäre der Key, seine Gesamtzeit der Value.
    Über assoziative Arrays hier schmökern.

    Du hattest wohl die indirekte Expansion im Sinn.
    Die funktioniert aber nur anders rum:

    Shell-Script

    1. red="rote Farbe"
    2. green="grüne Farbe"
    3. color=red
    4. echo ${!color}
    5. color=green
    6. echo ${!color}
    Sokrates sagte, dass er nichts wisse.
    Ich bin viel, viel klüger als Sokrates.
    Ich weiß ganz genau, dass ich gar nichts weiß.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Berichtigung ()

    Für den Inhalt des Beitrages 103755 haftet ausdrücklich der jeweilige Autor: Berichtigung

www.cyberport.de