Schleife die auf Interrupt reagiert MUSS EIN "tail -f Datei" nachbauen



  • Hallo Leute,

    ich habe ein kleines Problem, ich möchte ein Programm schreiben, was immer die letzte Zeile einer Datei ausgibt, wenn sich die Datei ändert.

    Jetzt werden alle halt schreien und mich drauf hinweisen das es soetwas im Linux/Unix schon gibt (man tail) ⚠
    Das ist korrekt, genauso möchte ich das programmieren. Ich habe nämlich das Problem, das "tail -f datei" funktioniert aber unter Unixware kann ich die Ausgabe nicht stoppen, ich gelange nicht auf die Shell zurück. Unter Linux kann ich mit Strg+C abbrechen und bin wieder in der Shell. Bei Unixware muss ich die Terminalsitzung killen oder wenn ich an der Konsole das mache, eine 2.Konsole öffnen und dann den Prozess kill. Das nervt.

    Also will ich mir ein Programm schreiben, was genau das selbe macht, bloss auf eine Tastenkombination Strg + c reagiert.

    1. Frage, wie Programmiere ich eine Schleife, die solange abgearbeitet wird bis ich Strg +c drücke.

    2. Frage, wie kann ich checken, das nur die letzte Zeile ausgeben wird,wenn sich was ander Datei ändert? 😕

    Danke für eure Hilfe. 🕶

    Gruss Alex ⚠ [b]



  • 1. Du erkennst STRG+C indem du das Signal SIGINT fängst und verarbeitest
    2. Schau dir am besten den Sourcecode von tail an. Ich glaube tail schaut sich einfach einmal in der Sekunde die Datei an, positioniert den Dateizeiger auf das bisherige Ende und liest bis zum tatsächlichen Ende.



  • Ponto schrieb:

    1. Du erkennst STRG+C indem du das Signal SIGINT fängst und verarbeitest

    was muss ich dort auswerten, was kommt bei STRG+C zurück, kannst du mir einen kleinen tipp in form von C-Code geben.Wenn du zeit hast.

    Ponto schrieb:

    2. Schau dir am besten den Sourcecode von tail an. Ich glaube tail schaut sich einfach einmal in der Sekunde die Datei an, positioniert den Dateizeiger auf das bisherige Ende und liest bis zum tatsächlichen Ende.

    Finde bei Google nix, viell.stell ich mich auch zu blöd an?
    Im Durchlauf n-1 setze ich den Zeiger aufs Datei ende, im Druchlauf n setze ich den zeiger +1 und schaue ob da was kommt?

    Kann ich nicht checken ob sich die Datei verändert hat, dann lese die letzte Zeile aus? 😕

    Hab nicht dich grosse Ahnung von C/C++ 👎

    Gruss ALex



  • Ich würde eher überprüfen, warum das tail auf Unixware nicht auf STRG+C reagiert. Ich kann kaum glauben, dass es das nicht tut.



  • Hallo,

    das tail auf UxW reagiert nicht, es ist ein SCO UxW 7.1.3 keine reaktion auf STRG+C oder STRG+X

    Gruss ALex



  • Hallo,

    ich habe eine Idee, wie ich das "tail -f datei" nachbauen kann,
    ich habe eine Endloschleife, die auf "CTRL+C" reagiert und abbricht.
    In der Schleife öffne ich eine Datei, schiebe den Dateizeiger ans Ende und nehme die letzte Zeile und vergleiche diese mit einer gespeicherten Variablen, sind die Unterschiedlich, dann gebe ich die Zeile aus und speichere die aktuelle Zeile in meiner Variable.
    Wenn die letzte Zeile und die Variable gleich sind, dann macht das Programm nichts, bis zum nächsten Durchlauf.

    Ich hoffe das ist ein Guter Ansatz?
    Habe leider noch nicht den Source-Code von tail gefunden, das ich mal nachschauen könnte.

    Hat jmd noch eine Idee?

    Gruss Alex 😉



  • ftp://gentoo.oregonstate.edu/pub/gentoo/distfiles/
    http://www.codeproject.com/useritems/MakeLogic_Tail_20.asp

    da vielleicht?
    habs noch nicht selber nachgeschaut, aber da sollte es zu finden sein im 1. link, im 2. ist der sourcecode von sowas was du nachbauen willst, auch ein tail-klon.

    mfg,
    julian



  • Ponto schrieb:

    Ich würde eher überprüfen, warum das tail auf Unixware nicht auf STRG+C reagiert. Ich kann kaum glauben, dass es das nicht tut.

    Seh ich genauso.



  • Hallo,

    das Problem hat sich geändert, ich möchte jetzt das "tail -f datei" nicht nachbauen um das richtige tail zu ersetzen, ich möchte ein eigenes Programm schreiben, was wir die letzte Zeile, wenn sie sich geändert hat, per Netzwerk an einen Server schickt.

    Selbst wenn ich auf der Konsole das "tail -f datei" zum abbruch kriege,habe ich meine neue Aufgabe nicht gelöst.

    Meine neues Aufgabe ist, wenn sich die letzte Zeile in einer Datei ändert, will ich sie an einen Server schicken.
    Wie kann ich das Umsetzen, das mein Programm überprüft ob sich die letzte Zeile geändert hat und diese dann aus gibt?

    Würde die Idee mit meinen Dateizeiger funktionieren?

    @Julian__ : Danke für die Links, aber der 1. ist in Perl, der 2. in Java ... ich müßte mich erstmal in die Progr.Sprachen einarbeite 😕

    Gruss Alex



  • facebraker schrieb:

    Meine neues Aufgabe ist, wenn sich die letzte Zeile in einer Datei ändert, will ich sie an einen Server schicken.

    Und was willst Du machen, wenn sich vor der letzten Zeile was geändert hat? Oder wenn zB zwei neue Zeilen am Ende dazugekommen sind?

    Schau Dir mal man: diff(1) an und werde Dir darüber klar, was _genau_ Du machen möchtest.



  • Hallo,

    ich habe mich wirklich doof ausgedrückt 😞

    Ich habe ein Log-Datei, die wird von einem Programm immer gefüllt, ich möchte in meinem Programm überprüfen, wenn eine neue Zeile der Log-Datei angefügt wird, das das Programm das erkennt und diese neue Zeile per Socket an einen Server schickt, der diese dann weiter verarbeitet.
    Wenn also eine neue Zeile kommt, dann will ich es erkennen und die, im ersten Schritt, nur auf der Konsole ausgeben.
    z.B. ich habe eine Datei logfile.000, mein Programm soll in einer Endlosschleife immer schauen, ob eine neue Zeile angehängt wurde.
    Wenn ich dann cat "neue Zeile" >> logfile.000 sage, soll mein Programm dann auf der Konsole "neue Zeile" ausspucken, usw.?

    Das mit dem diff wäre eine Lösung, aber dann müßte ich ja immer die Datei(alt) zum Vergleich vorhalten?

    Sorry für meine schlechte erklärung! 👎

    Gruss Alex 😉



  • Wer füllt denn die Log-Datei mit Daten? Wenn das im Programm selber passiert, könntest du versuchen, die Log-Ausgaben im Programm umzuleiten und auszuwerten. Andernfalls wäre es noch eine Möglichkeit, in regelmäßigen Abständen die Größe der Log-Datei zu kontrollieren und bei Änderungen das letzte Stück der Datei zu lesen und auszugeben.



  • Hallo CSToll,

    die Logdatei wird von einem anderen Programm gefüllt, ich möchte die nur Überwachen, ich komme leider nicht ran, wie die Datei gefüllt wird.

    Ich möchte nur ein Programm schreiben, welches mir die Kontrolle abnimmt und bei neuen Zeilen, mir diese per Socket verschickt, oder im ersten Schritt nur auf der Konsole ausgibt.

    Das mit dem Größenvergleich wäre ne Möglichkeit, aber woher weiss ich welche Zeilen dann dazu gekommen sind, da würde ich ja wieder bei der Sache mit diff() sein?

    Was sagst Du/Ihr zu diesem Ansatz:

    In einer Endlosschleife öffne ich eine Datei, schiebe den Dateizeiger ans Ende und nehme die letzte Zeile und vergleiche diese mit einer gespeicherten Variablen, sind die Unterschiedlich, dann gebe ich die Zeile aus und speichere die aktuelle Zeile in meiner Variable.
    Wenn die letzte Zeile und die Variable gleich sind, dann macht das Programm nichts, bis zum nächsten Durchlauf.
    Im ersten Durchlauf ist die Variable leer, dann ergibt der Vergleich mit der letzten Zeile dass sie ungleich sind, und ich schicke die Zeile weg.
    Nun speichere ich die Zeile als Variable. ich öffne wieder die Datei, schiebe mit fseek/SEEK_END wieder ans Dateiende und vergleiche diese Zeile mit der gespeicherten Variablen, wenn sie gleich sind, dann macht er nix, wenn sie ungleich sind, dann schicke die Zeile weg.... usw.

    Idee?

    Gruss Alex 😉



  • facebraker schrieb:

    Das mit dem Größenvergleich wäre ne Möglichkeit, aber woher weiss ich welche Zeilen dann dazu gekommen sind, da würde ich ja wieder bei der Sache mit diff() sein?

    Dazu mußt du wissen, wie die Logdatei gefüllt wird. Im typischen Anwendungsfall hängt das schreibende Programm jeden neuen Eintrag ans Dateiende an, das heißt die (gemerkte) alte Größe der Datei wäre der Anfangspunkt für die neu hinzugekommene Zeile.

    //Achtung - ungetestet
    int fsize=0;
    while(true)
    {
      FILE* log=fopen("log.txt","rb");
      fseek(log,0,SEEK_END);
      int nsize=ftell(log);
    
      if(nsize!=fsize)
      {
        fseek(log,fsize,SEEK_SET);
        int c;
        while((c=fgetc(log))!=EOF) putc(c,log);
      }
      fsize=nsize;
      fclose(log);
    }
    


  • Hallo CSToll,

    danke für die Lösung, ich habe deinen Code getestet und angepasst, es funktioniert sehr gut 💡 ! Danke

    //CODE getestet
    int fsize=0;
    char zeile[512];
    while(1)
    {
      FILE* log=fopen("log.txt","rt");
      fseek(log,0,SEEK_END);
      int nsize=ftell(log);
    
      if(nsize!=fsize)
      {
        fseek(log,fsize,SEEK_SET);
        int c;
        while(fgets(zeile,sizeof(zeile),log)!=0 )
        {
         printf("%s",zeile);
        }
    
      }
      fsize=nsize;
      fclose(log);
    }
    return 0;
    }
    

    Danke für deine Hilf und die Idee mit dem Zeilenvergleich(ftell) 💡 ! 👍

    Gruss ALex



  • *edit* am kontext vorbeigetextet 🙂


Anmelden zum Antworten