Schlagwort-Archive: tee

STDOUT verdoppeln mit ftee

Mal wieder eine etwas andere Anforderung: Für eine automatische Verarbeitung soll eine Audioquelle durch eine Software auf der Konsole ausgewertet werden. Die Software ist hierbei für die Analyse von Dateien ausgelegt, kann allerdings auch von STDIN lesen. So weit kein Problem – arecord kümmert sich um die Aufnahme und per STDOUT/Pipe geht es in die Analysesoftware. Leider gibt es hier einen Haken: Es funktioniert nicht zuverlässig. Um zu prüfen ob die Audioquelle oder die Analyse das Problem verursacht müsste ich die eingehenden Audiodateien abhören. Am PC ginge das mit Pulseaudio recht einfach, am Server möchte ich auf dieses Ressourcen- und Dependency-Monster jedoch vorzugsweise verzichten.

Dann halt per File

Meine erste Idee: tee. Mit diesem Befehl kann man die Dateien einer Pipe in eine zusätzliche Datei „abzwacken“:

arecord hw:1,0 | tee test.daten | analyzer -

Was prinzipiell funktioniert hat jedoch einen entscheidenden Nachteil: Es landet alles in der Datei. Dauerhaft. Möchte man nicht, dass die Festplatte voll läuft, muss man nach dem reinhören das Konstrukt abbrechen und ohne tee-Befehl neu starten. Eher unschön, denn das heißt auch Deattime, also eine kurze Zeitspanne in der ich möglicherweise Ereignisse verpasse.

Und was ist mit FIFO?

Als Alternative eignet sich ein FIFO, auch als named Pipe bezeichnet. Diese lassen sich mit mkfifo anlegen und stellen sozusagen einen „Puffer“ zur Verfügung, über den sich Prozesse verbinden lassen. Hier können wir im ersten Terminal z.B. wie folgt starten:

mkfifo test.fifo
arecord hw:1,0 | tee test.fifo | analyzer -

und im Zweiten den Stream abgreifen

cat test.fifo > test.daten

Dummerweise gibt es auch hier Probleme: Es blockiert. Der Analyzer im ersten Terminal wird erst gestartet, wenn wir im Zweiten beginnen den Puffer zu lesen. Schlimmer noch: Brechen wir im zweiten Terminal das Mitlesen ab wird auch der Analyzer beendet. Nicht wirklich was ich suche.

Dauer-Interimslösung

Nunja, da mir die Ideen ausgingen und das Internet auf den ersten Blick nichts passendes lieferte blieb es erst mal bei der dauerhaften Dateiaufzeichnung auf einen speziell limitierten Ordner. Lief alle paar Wochen die zugehörige Partition voll brach die Software ab und ich startete per Hand neu. Auf der Todo-Liste stand etwas von automatischen Neustarts oder einem Gebastel um nur bei Bedarf die Ausgabe zur named Pipe zu starten. Dieser Zustand hielt nun für etwa 2 Jahre.

Rettung bei Stackoverflow

Heute ging es dann um die Behebung. Ich hatte grade ein Rendering gestartet und entsprechend etwas Leerlauf als die altbekannte Mail kam: Partition voll, die Erkennung steht. Jetzt reicht es. Also schnell auf Google und etwas in die Verwendung von Named Pipes einlesen.

Moment.

Nach kurzer Recherche landete ich bei Stackoverflow (wo auch sonst). Nach „Linux non-blocking fifo“ erkundigt sich der Autor „Dronus“ und beschreibt ein Szenario, welches recht Nah an meine Andorderungen heran kam. Und Beantworter „racic“ lieferte auf ganzer Linie: „ftee“ nennt sich sein überschaubarer C-Code, welcher das verhalten von tee nachmacht, jedoch für den FIFO nicht blockiert. Auch wird SIGPIPE, welches beim Abbrechen des Lesevorgangs der Pipe ausgelöst wird, nicht beachtet, der Analyzer läuft also fleißig weiter. Greift man später erneut auf die Pipe zu erhält man wieder die aktuellen Daten.

Wer „wichtige“ Daten nutzt kann alternativ auf das ebenfalls dort zu findende bftee von Fabraxias zurückgreifen, welches bei einem Abbruch der Verbindung alle eingehenden Daten zwischenspeichert und bei der nächsten Verbindung erst einmal nachliefert.

Für mich ist die nicht gepufferte Variante ideal – alte Audiodaten sind für mich nicht relevant. Das Kompilieren ist mit aktuellem GCC schnell erledigt und allein das ersetzen von tee gegen ftee im vorherigen Beispiel löst alle Probleme. Der Analyzer läuft und ich kann bei Bedarf in den Audiostream reinhören ohne eine Unterbrechung der Auswertung zu bekommen. Fein.