2016-03-31 3 views
1

Ich versuche, das folgende Bash-Skript, um zu laichen und seine stdout erfassen asynchron:Beaufsichtigen Input eines Spawned Prozess

#!/bin/bash 

sleep 2; 
echo "one"; 
sleep 2; 
echo "two"; 
sleep 2; 
echo "three"; 
# ... possibly infinite.. 

Hier wird der Java-Code ist so weit:

ProcessBuilder pb = new ProcessBuilder("sleeper"); 
Process process = pb.start(); 
InputStream input = process.getInputStream(); 

// now I continue in pseudo-code: 

supervise the input-stream. 
whenever a new line arrives: 
    check if the line equals "two"; 
     then: doSomeAction(); 

Hinweis: I Ich schreibe das Programm nicht wirklich in Java. Ich schreibe es in Clojure, aber ich habe noch keinen Clojure-Ansatz dafür gefunden. Also versuche ich die native Java-API zu verwenden, die von Clojure umschlossen ist.


ein NodeJS Beispiel

Tho meine Absicht, ein bisschen mehr klären, hier ist ein JavaScript-Code für Node.JS, die genau tut, was ich will:

const spawn = require('child_process').spawn; 
const sleeper = spawn('sleeper'); 

sleeper.stdout.on('data', (data) => { 
    if (data.toString() === "two\n") { 
     doSomeAction(); 
    } 
}); 
+0

Soll die Verarbeitung des Eingabedatenstroms in einem separaten Thread erfolgen und von einem anderen Thread gesteuert werden? Oder sollte es den Prozess nur behandeln, bis er bestimmte Daten erhält oder der Prozess endet? –

+0

Nein, soweit ich das beurteilen kann, ist kein separater Thread notwendig. Der Subprozess ("Schläfer") ist keine schwere Computeranwendung. Es ist eigentlich ein Unix-Tool, das einen kleinen Server ausführt, so dass es wirklich unendlich läuft. Wichtig für meine Anwendung ist jedoch, dass sie während der Überwachung des Unterprozesses nicht blockiert ist. Alles andere sollte weitergehen ... –

Antwort

2

können Sie Verwenden Sie die Tools in clojure.java.io zusammen mit einfachen Java-Interop.

Hier einige Code, den Sie zu erhalten begonnen:

(require '[clojure.java.io :refer [reader]]) 

(let [process (.start (ProcessBuilder. ["./sleeper"]))] 
    (with-open [r (reader (.getInputStream process))] 
    (doseq [line (line-seq r)] 
     (when (= line "two") 
     (println line))))) 

diese in Ihre REPL einfügen und Sie sollten two ausgegeben wird nach der entsprechenden Verzögerung sehen.

+1

Sie könnten es auch in ein 'future' verpacken, damit Ihr Hauptanwendungsthread nicht blockiert wird und weiter ausgeführt werden kann. –

+0

@PiotrekBzdyl Richtig. - Ich habe gerade bemerkt, dass die Frage nach einer Lösung fragt, die den Hauptthread nicht blockiert. Ich habe das Gefühl, dass ich das nicht beantworten kann, ohne zu wissen, was das Programm im Hauptthread macht ... viel Glück! – glts

+0

nett! das macht genau das, was es sollte .. –