Daten aus laufenden Prozess in Datenbank schreiben

  • Hallo zusammen :)

    Ich bastle derzeit an einem Projekt, bei dem via Funk empfangene Daten in einem Webinterface dargestellt werden sollen.

    Um die Daten darzustellen, sollen diese zuvor in eine Datenbank geschrieben werden:
    Datenempfang (läuft dauerhaft) -> SQLite -> Auswertung in PHP

    Die eigentliche Datenausgabe des Empfangsprozesses sieht so aus:

    NEWMESSAGE: RECIPIENT: 1234567 MSG: Dies ist ein Test!
    NEWMESSAGE: RECIPIENT: 1234 MSG: Hallo Welt
    NEWMESSAGE: RECIPIENT: 99999MSG: Noch eine Nachricht
    NEWMESSAGE: RECIPIENT: 789 MSG: Das Raspberry Pi Forum ist toll

    Der Prozess schreibt auf die STDOOUT und gibt mir die Meldungen derzeit in der BASH aus.
    Dabei endet der Prozess nicht, sondern wartet immer bis neue Nachrichten kommen und gibt diese dann aus.

    Wie kann ich nun die Nachrichten bzw. z.B. den Empfänger und die Nachricht im laufenden Prozess "rausfischen" und in eine Datenbank schreiben?

  • Daten aus laufenden Prozess in Datenbank schreiben? Schau mal ob du hier fündig wirst!

  • Ich benutze einen RTL-SDR USB Stick und RTL_FM um ein Funksignal zu empfangen. Dieses Signal gebe ich über eine Pipe an einen Dekoder, welcher mir im Terminal diese Ausgabe gibt:


    NEWMESSAGE: RECIPIENT: 1234567 MSG: Dies ist ein Test!
    NEWMESSAGE: RECIPIENT: 1234 MSG: Hallo Welt
    NEWMESSAGE: RECIPIENT: 99999MSG: Noch eine Nachricht
    NEWMESSAGE: RECIPIENT: 789 MSG: Das Raspberry Pi Forum ist toll

    Dieser Dekoder ist in C geschrieben (nicht von mir). Ich habe diese Terminalausgabe schon in eine einfache Textdatei umgeleitet. Das hat gut funktioniert, jedoch würde ich (wenn das geht) in eine Datenbank schreiben um später in PHP besser darauf zugreifen zu können.

  • Naja ich bin letzt leider genau so schlau wie vorher =( Ich weiß leider immer noch nicht wie du es aufrufst.. poste doch mal bitte den Befehl den du ausführst um eine Ausgabe zu erhalten :huh:

    Ich weiß nämlich nicht wieso du bereits eine Pipe verwendest bzw was diese Pipe oder der Dekoder bewirkt ... Ansonsten würde ich einfach mal sagen das du Script benötigst was diesen besonderen Befehl ausführt und weiter verarbeitet :D
    (nun biste vermutlich genauso schlau wie ich zuvor :lol:)

  • Hi,


    ... jedoch würde ich (wenn das geht) in eine Datenbank schreiben um später in PHP besser darauf zugreifen zu können.


    welchen Vorteil versprichst Du Dir davon, wenn Du einfach plain Text in eine DB schreibst?
    Da kannst Du auch nichts anderes mit machen, als mit Standard-Linux-Boardmitteln.

    Ansonsten: C-Programm umschreiben, connect an den Anfang und statt der printf/fprintf inserts in die DB ...

    cu,
    -ds-

  • Hier der Aufruf:
    rtl_fm -s <SAMPLINGRATE> -f <FREQUENZ> - | multimon-ng -t raw -a <KODIERUNG> -

    Dies gibt mir bei jeder neuen Nachricht eine Zeile aus. Der Prozess endet dabei aber nicht, da ja immer weiter geschaut wird ob etwas empfangen wird.


    welchen Vorteil versprichst Du Dir davon, wenn Du einfach plain Text in eine DB schreibst?
    Da kannst Du auch nichts anderes mit machen, als mit Standard-Linux-Boardmitteln.


    Ich möchte in der Tabelle im Idealfall ein Attribut "Timestamp", "Empfänger" und "Nachricht" haben. So kann ich einfach nach Zeiträumen oder Empfängern suchen.

    Einmal editiert, zuletzt von heytux (23. Januar 2015 um 14:49)

  • Naja was er sich davon verspricht ist doch eher egal - wieso/weshalb/warum jemand das so möchte muss man nicht ständig hinterfragen... Wenn er einfach nur sich ausgeben lassen möchte wann welche Nachricht von wem verschickt wurde. Und ob nun Textdatei oder Datenbank, da würde ich persönlich auch letzteres bevorzugen.


    Ich zeig dir mal ein bash Script mit dem du einen Befehl ausführen und die Ausgaben verarbeiten kannst - probier das mal bitte aus und poste die Ausgabe (aber mit Deinem Befehl):

    Code
    while read line; do
            if [[ "$line" = *"CRON"* ]]; then
                    echo "NEW LINE: $(date)"
                    echo $line
            fi
    done < <(tail -f /var/log/syslog)

    ..das Script läuft so lange wie der Befehl aktiv ist, in diesem Fall also ewig da "tail -f /var/log/syslog" immer wieder neue Zeilen der Logdatei ausgibt
    Ausgabe:

    Spoiler anzeigen

  • ... Und ob nun Textdatei oder Datenbank, da würde ich persönlich auch letzteres bevorzugen.


    Prinzipiell würde ich Dir recht geben, aufgrund der Resourcenlage des RPi würde ich persönlich auf die DB verzichten, wenn ein Textfile genau so tut. Die zugehörige Anwendung läuft - je nach Komplexität - mit Sicherheit um einiges schneller als mit myql im Genick ;)


    ... ein Attribut "Timestamp", "Empfänger" und "Nachricht" haben. So kann ich einfach nach Zeiträumen oder Empfängern suchen.

    na dann ...
    würde ich eine pipe (fifo) anlegen:

    Code
    mkfifo hugo


    und die Ausgabe des Programm in diese Pipe schicken:

    Code
    rtl_fm -s <SAMPLINGRATE> -f <FREQUENZ> - | multimon-ng -t raw -a <KODIERUNG> - > ./hugo


    bzw. wenn multimon-ng das unterstützt, statt - eben ./hugo

    Das Ganze schickst Du in den Hintergrund (CTRL-Z / bg) ...

    Jetzt ist es möglich, z.B. basierend auf meigrafds script, die Pipe in einer Endlosschleife zeilenweise auszulesen, die Daten zu zerpflücken und mit insert in die DB zu schreiben.

    cu,
    -ds-

  • Was soll denn " ./hugo " bewirken? Das ist doch nur eine Datei, kein Script ;)

    Aber verstehe nicht was das bringen soll. Bevor er son kuddelmuddel macht kann er auch gleich nur mein Script nehmen, ohne Umweg über eine FIFO Datei und dann auch noch tail dazu usw... das wäre etwas übertrieben/oversized :D

    Aber nun gut, lass ihn das erst mal mit meinem Script testen, dann kann man weiter gucken


  • Was soll denn " ./hugo " bewirken? Das ist doch nur eine Datei, kein Script ;)

    Aber verstehe nicht was das bringen soll.
    ...


    Das ist eine FIFO und hat den Vorteil, dass Du die Daten auch von einem anderen Terminal, einem anderen Rechner, im Hintergrund, ... lesen kannst.
    Damit bist Du weg von stdin/stdout/stderr ...
    Ausserdem geht nichts verloren ... selbst wenn der Leseprozess mal abkackt.

    cu,
    -ds-

  • Durch die Kombination der FIFO Pipe und des Scripts von meigrafd kann ich die Ausgabe zeilenweise auswerten :thumbs1:

    Das Script alleine funktioniert nicht. Das liegt wohl daran, weil

    Code
    done < <(rtl_fm -s <SAMPLINGRATE> -f <FREQUENZ> - | multimon-ng -t raw -a <KODIERUNG> -)


    auf ein Ende des Streams wartet.

    Leite ich die Ausgabe von multimon-ng in die FIFO Pipe, kann ich über das Script daraus lesen.
    Das einzige Problem auf das ich gestoßen bin: Beende ich das Script, beendet sich auch der Empfangprozess (rtl_fm/multimon-ng) sobald eine weitere Nachricht empfangen wird die dann nicht mehr vom Script ausgelesen wird. Kann es sein, dass die Pipe beim Beenden des Scripts "bricht"?

  • Hi,


    ...
    ... Kann es sein, dass die Pipe beim Beenden des Scripts "bricht"?


    hab' ich das richtig verstanden: wenn Du das Programm rtl_fm beendest, dass beendet sich auch multimon-ng?
    Naja ... ich meine, das ist irgendwie logisch. Da kommt ein EOF bei multimon-ng an und es nimmt an, dass Ende ist ...
    Rein theoretisch könntest Du eine weitere named pipe anlegen (vielleicht Kathi, damit der Hugo nicht so allein ist ;) ...) , mit rtl_fm dort hinein schreiben und mit multimon-ng daraus lesen.

    Du kannst auch mit Umleitungen ( > bzw. >> oder < ) in eine solche pipe schreiben und daraus lesen. cat geht auch ...

    cu,
    -ds-


  • hab' ich das richtig verstanden: wenn Du das Programm rtl_fm beendest, dass beendet sich auch multimon-ng?

    Das wäre ja klar :D Nein, folgende Situation:

    1. Terminal

    Code
    rtl_fm -s <SAMPLINGRATE> -f <FREQUENZ> - | multimon-ng -t raw -a <KODIERUNG> - > ./hugo

    rtl_fm empfängt munter und gibt die raw-Daten weiter | multimon-ng dekodiert die Daten und gibt sie an den hugo ;)

    2. Terminal

    Code
    sudo bash meigrafds_script.sh


    Hier läuft nun Meigrafd's Script, so angepasst, dass es aus hugo ließt.
    Bis hier ist alles :thumbs1:
    Beende ich nun dieses Script mit CTRL-C beendet sich nun aber auch rtl_fm.
    Das Ganze passiert nicht direkt bei CTRL-C, sondern (so vermute ich) wenn eine neue Nachricht empfangen wurde.

    Also rtl_fm > multimon-ng > hugo > script ließt hugo
    script mit CTRL-C beendet > rtl_fm wird beendet mit

    Code
    Signal caught, exiting!
    User cancel, exiting...

  • Wie hast Du das Konstrukt denn aufgerufen?
    Ich vermute jetzt mal, dass das SIGINT bis zum rtl_fm-Prozess durchkommt ... :s

    Das Phänomen hab ich auch schon beobachtet.

    Konstrukt:

    Code
    mkfifo /tmp/hugo
    tail -f /var/log/syslog > /tmp/hugo

    Ein 2.Terminal öffnen und dort:

    Code
    cat /tmp/hugo

    Beendet man nun den cat Befehl, wird nach ca. 5 Sekunden auch der tail Befehl im 1.Terminal beendet.

    Kurios ist aber das nur eine Umleitung in eine Richtung stattfindet, also nach /tmp/hugo
    aber keine in die andere Richtung.

    :denker:


  • Wie hast Du das Konstrukt denn aufgerufen?

    1. Terminal:

    Code
    rtl_fm -s <SAMPLINGRATE> -f <FREQUENZ> - | multimon-ng -t raw -a <KODIERUNG> - > ./hugo

    2. Terminal:

    Code
    sudo bash script.sh


    Inhalt:

    Bash
    #!/bin/bash
    while true
       do
          if read line; then
             echo "NEW LINE: $(date)"
             echo $line
       fi
    done < /home/pi/Desktop/testing/hugo

    EDIT: Beide Terminals natürlich in /home/pi/Desktop/testing/

    Einmal editiert, zuletzt von heytux (23. Januar 2015 um 19:11)

  • hm ...
    mit einem

    Code
    trap '' 13


    am Anfang des writers sollte es durchlaufen ... ich probier' das grade aus.

    //EDIT:
    Ok, also dieser script:

    Bash
    #!/bin/bash
    #trap "echo ich habe ein SIGPIPE erwischt" 13
    trap '' 13
    #
    find / -print > ./hugo


    in einem Terminal aufgerufen läuft weiter, auch wenn ich im anderen Terminal

    Code
    cat ./hugo


    aufrufe und den cat mit CTRL-C beende ...

    cu,
    -ds-

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!