2009-11-13 26 views
16

पर रीडायरेक्ट करें I groovy प्रोग्राम के भीतर से foo.bat निष्पादित करना चाहते हैं और परिणामस्वरूप प्रक्रिया 'आउटपुट को stdout पर रीडायरेक्ट किया गया है। या तो जावा या ग्रोवी कोड उदाहरण ठीक होगा।रीडायरेक्ट प्रक्रिया आउटपुट को

foo.bat को चलाने के लिए कई मिनट लग सकते हैं और बहुत सारे आउटपुट उत्पन्न कर सकते हैं, इसलिए मैं आउटपुट को जल्द से जल्द देखना चाहता हूं, जब तक कि सभी आउटपुट देखने से पहले प्रक्रिया पूरी नहीं हो जाती तुरंत।

+0

http://stackoverflow.com/questions/1670798/using-a-thread-to-capture-process-output – yegor256

उत्तर

29

यह एक वर्ग का उपयोग करता है जो निष्पादित प्रोग्राम के सभी आउटपुट को पढ़ता है और इसे अपने स्वयं के stdout में प्रदर्शित करता है।

class StreamGobbler extends Thread { 
    InputStream is; 

    // reads everything from is until empty. 
    StreamGobbler(InputStream is) { 
     this.is = is; 
    } 

    public void run() { 
     try { 
      InputStreamReader isr = new InputStreamReader(is); 
      BufferedReader br = new BufferedReader(isr); 
      String line=null; 
      while ((line = br.readLine()) != null) 
       System.out.println(line);  
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
} 

Runtime rt = Runtime.getRuntime(); 
Process proc = rt.exec("javac"); 
//output both stdout and stderr data from proc to stdout of this process 
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream()); 
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream()); 
errorGobbler.start(); 
outputGobbler.start(); 
proc.waitFor(); 
+1

मेरा प्रश्न है के लिए इसी तरह, अगर प्रक्रिया पल में सामान outputting नहीं है क्या प्रक्रिया खत्म होने से पहले लूप खत्म हो जाएगा, है ना? –

+0

जबकि लूप इनपुट की अगली पंक्ति तक प्रतीक्षा करेगा। – Crummy

4

यदि आप बस एक साधारण कमांड के आउटपुट को पकड़ने की कोशिश कर रहे हैं तो यहां कुछ आसान है। यदि आप समानांतर में प्रक्रिया करना चाहते हैं या यदि आपका आदेश stdin लेता है या stderr उत्पन्न करता है तो आपको जिटर की तरह थ्रेड का उपयोग करना होगा।

यदि आप बहुत सारे आउटपुट प्राप्त कर रहे हैं तो एक buffered प्रति (जैसे this) का उपयोग करें।

import java.io.*; 
public class test { 
    static void copy(InputStream in, OutputStream out) throws IOException { 
    while (true) { 
     int c = in.read(); 
     if (c == -1) break; 
     out.write((char)c); 
    } 
    } 

    public static void main(String[] args) throws IOException, InterruptedException { 
    String cmd = "echo foo"; 
    Process p = Runtime.getRuntime().exec(cmd); 
    copy(p.getInputStream(), System.out); 
    p.waitFor(); 
    } 
} 
4

निम्नलिखित ग्रूवी कोड foo.bat निष्पादित और stdout में उत्पादन भेज देंगे: इसे प्राप्त करने के

println "foo.bat".execute().text 
+4

मुझे लगता है कि यह प्रक्रिया पूरी होने के बाद ही सभी आउटपुट प्रिंट करेगी। मैं उत्पादन को –

+1

उत्पन्न होने के तुरंत बाद देखना चाहता हूं, अगर यह foo.bat का आउटपुट stdout buffer के लिए "बहुत बड़ा" है, तो यह foo.bat के निष्पादन को रोक देगा। – billjamesdev

2

अतुल्यकालिक रास्ता।

void inputStreamToOutputStream(final InputStream inputStream, final OutputStream out) { 
    Thread t = new Thread(new Runnable() { 

     public void run() { 
      try { 
       int d; 
       while ((d = inputStream.read()) != -1) { 
        out.write(d); 
       } 
      } catch (IOException ex) { 
       //TODO make a callback on exception. 
      } 
     } 
    }); 
    t.setDaemon(true); 
    t.start(); 
} 

{ 
    Process p = ...; 
    inputStreamToOutputStream(p.getErrorStream(), System.out); 
    inputStreamToOutputStream(p.getInputStream(), System.out); 
} 
6

आप अधिक ग्रूवी और कम जावा के साथ ऐसा करने के लिए देख रहे हैं, यह प्रत्येक पंक्ति प्रिंट होगा के रूप में यह होता है:

def cmd = "./longRunningProcess" 

def process = cmd.execute() 
process.in.eachLine { line -> println line } 

वैकल्पिक रूप से, यदि आप दोनों stdout और stderr

दोनों देखना चाहते हैं
35

विरासत() विधि का उपयोग कर अपने सभी स्ट्रीम को मानक आउटपुट पर रीडायरेक्ट करना आसान है। यह आउटपुट को उस प्रक्रिया के stdout पर प्रिंट करेगा जिससे आप इस कमांड को चला रहे हैं।

ProcessBuilder pb = new ProcessBuilder("command", "argument"); 
pb.directory(new File(<directory from where you want to run the command>)); 
pb.inheritIO(); 
Process p = pb.start(); 
p.waitFor(); 

अन्य विधियों भी मौजूद हैं, जैसा कि नीचे उल्लिखित है। ये व्यक्तिगत विधियां केवल आवश्यक स्ट्रीम को पुनर्निर्देशित करने में मदद करेंगी।

pb.redirectInput(Redirect.INHERIT) 
    pb.redirectOutput(Redirect.INHERIT) 
    pb.redirectError(Redirect.INHERIT) 
+1

यह वह उत्तर है जो प्रश्न का सही उत्तर देता है। ओपी ने आउटपुट को रीडायरेक्ट करने के लिए कहा, आउटपुट की प्रत्येक पंक्ति को प्रिंट करने के लिए नहीं। बहुत महत्वपूर्ण अंतर – Brandon

+1

मैं इसे पर्याप्त रूप से ऊपर नहीं उठा सकता, आपने मुझे बहुत मदद की है। –

संबंधित मुद्दे