2012-02-09 17 views
6

हम यह पता लगाने की कोशिश कर रहे हैं कि एक जावा एप्लिकेशन को एक पर्ल स्क्रिप्ट के भीतर से कैसे चलाया जाए लेकिन फिर भी जावा ऐप के STDOUT से समय-समय पर पढ़ सकें।मैं एक पर्ल प्रोग्राम से चल रहे प्रोग्राम के STDOUT को कैसे देख सकता हूं जिसे इसे कहा जाता है?

print "running dcmrcv.bat\n"; 

open my $fh_dcmrcv, "-|", 'z:\apps\dcm4che\dcm4che-2.0.26\bin\dcmrcv.bat \ 
    DCMRCV:11112 -dest z:\dcmrcv -journal z:\dcmrcv', 
    or die "could not execute dcmrcv: $!"; 

print "dcmrcv.bat started\n"; 

हम filehandle, $ fh_dmcrcv से पढ़ने में सक्षम होना चाहते थे, हर कुछ मिनटों या शायद ट्रिगर कब एक AnyEvent की स्थापना जब वहाँ filehandle पर गतिविधि है द्वारा।

हालांकि, जब मैं कोशिश करते हैं और filehandle से पढ़ें, यह ब्लॉक अगर मैं कुछ इस तरह का उपयोग करें:

foreach my $line (<$fh_dmcrcv>) { 
    print $line; 
} 

हम कई दृष्टिकोण की कोशिश की है, नहीं लगता है कि हम फ़ाइल :: पूंछ का उपयोग कर सकते है, चूंकि ऐसा लगता है कि मॉड्यूल को एक वास्तविक फ़ाइल की आवश्यकता है। ऐसा लगता है कि जब हम इसे पढ़ते हैं तो $ fh_dcmrcv हमें अवरुद्ध कर रहा है, हम वास्तव में सही दृष्टिकोण के बारे में सुनिश्चित नहीं हैं कि हम क्या चाहते हैं।

संपादित करें # इस तरह 1

हम अपने पर्ल स्क्रिप्ट चलाने हम देख रहे हैं उत्पादन: msgs

Z:\projects\demo_2>process_files.pl 
running dcmrcv.bat 
dcmrcv.bat started 
Start Server listening on port 11112 
11:55:13,495 INFO - Start listening on 0.0.0.0/0.0.0.0:11112 

स्क्रिप्ट, process_files.pl उत्सर्जित करती है .:

running dcmrcv.bat 
dcmrcv.bat started 

संदेश। जावा कार्यक्रम से कर रहे हैं: प्रारंभ सर्वर पोर्ट पर ध्यान 11112 11: 55: 13,495 जानकारी - 0.0.0.0/0.0.0.0:11112

पर सुन इस मामले में हम सिर्फ खातिर उन बाहर गूंज रहे हैं शुरू इस सवाल के, वास्तव में हम कुछ संदेशों के लिए समय-समय पर विश्लेषण करना चाहते हैं। और उनमें से किसी को भी गूंज नहीं।

किसी भी अंतर्दृष्टि की सराहना की है,

-Sam

+1

क्या आप एप्लिकेशन आउटपुट को (अस्थायी) फ़ाइल में लिख सकते हैं, और फिर 'फ़ाइल :: टेल' का उपयोग कर सकते हैं? – mob

+0

हम उस दृष्टिकोण से बचने की कोशिश कर रहे हैं। हम इसे घुमाने या इसे ट्रिम करने के संदर्भ में इस फ़ाइल को प्रबंधित नहीं करना चाहते हैं। – slm

+1

क्या आपने वर्णनकर्ता को O_NONBLOCK पर सेट करने के लिए fctrl का उपयोग करने का प्रयास किया है? – frankc

उत्तर

4

अधिकांश सिस्टम 4-तर्क select फ़ंक्शन का समर्थन करते हैं (IO::Select में अच्छी तरह से पैक किया गया है) जो आपको बता सकता है कि सॉकेथैंडल या पाइपहेडल पर इनपुट प्रतीक्षा है या नहीं।Windows में, select केवल सॉकेट पर समर्थित है, जो इस बीजान्टिन समाधान की ओर जाता है:

  1. सॉकेट जोड़ी
  2. कांटा बना सकते हैं और एक बच्चे की प्रक्रिया
  3. बच्चे प्रक्रिया में में कमांड चलाएँ, आदेश उत्पादन को पुनः प्राप्त और सॉकेट
  4. माता-पिता में करने के लिए इसे लिखने का चयन करें का उपयोग करें और के रूप में वांछित सॉकेट पर कार्रवाई पढ़

उदाहरण:

use Socket; 
use IO::Select; 
use Time::HiRes; 
$cmd = $^X . ' -MMath::BigInt -e "$_=1; ' 
     . 'print qq/$_!=/,Math::BigInt->new($_)->bfac(),qq/\n\n\n/' 
     . ' for 4000..4100"'; 
socketpair A,B,AF_UNIX,SOCK_STREAM,PF_UNSPEC; # step 1 
if (fork() == 0) { 
    open my $fh, '-|', $cmd;     # step 2 
    while (<$fh>) { 
     print B;        # step 3 
    } 
    close $fh; 
    exit $? >> 8; 
} 
$s = IO::Select->new(); 
$s->add(\*A); 
for (;;) { 
    if ($s->can_read(0.25)) {     # step 4 
     $line = <A>; 
     print "Do something with command output: $line"; 
    } else { 
     print "No output now. Could be doing something else ...\n"; 
     Time::HiRes::sleep(0.25); 
    } 
} 

क्या आप वाकई अपने कमांड आउटपुट को अस्थायी फ़ाइल में लिखना नहीं चाहते हैं?

+0

यह 9 0% काम किया। सॉकेट के बफर को लंबित सभी आउटपुट को फ्लश करने के लिए मुझे 'प्रिंट बी' के ठीक बाद 'बी-> फ्लश' जोड़ना होगा। – slm

+0

मुझे यह स्वीकार करने में दर्द होता है क्योंकि यह सॉकेट मॉड्यूल के माध्यम से सुरंग आईओ का उपयोग करने में कुल हैक है लेकिन मैं इसके अलावा काम करने वाले किसी भी अन्य दृष्टिकोण के साथ आने में सक्षम नहीं हूं। तो बधाई हो, यह सबसे अच्छा जवाब है जो मुझे मिल सकता है। – slm

+1

धन्यवाद @ एसआईएम। पोर्टेबिलिटी एक कुतिया है। – mob

0

इस बजाय साथ पढ़ने की कोशिश: पढ़ने के लिए

while (my $line = <$fh_dmcrcv>) { 
    print $line; 
} 

संबंध

+0

इस और एक ही परिणाम की कोशिश की गई। फाइलहैंडल से पढ़ना पर्ल प्रोग ब्लॉक करता है। – slm

+1

आप सही हैं। शायद आप यह जांचना चाहें कि क्या आपका सिस्टम गैर-अवरुद्ध विकल्प के साथ फ़ाइल खोलने का समर्थन करता है, इसलिए फ़ाइल डिस्क्रिप्टर से पढ़ने के लिए कुछ भी नहीं है तो पढ़ना बंद नहीं होगा। आपको पर्ल के सिसोपेन – quicoju

2

उपयोग IO::Select या चार तर्क select() जब पढ़ने नहीं होगा ब्लॉक। संपादित करें: कभी नहीं, आप on Windows हैं, इसलिए यह काम नहीं करेगा। एक विकल्प: इस पाइप से मध्यस्थ प्रक्रिया पढ़ें और एक मध्यस्थ फ़ाइल को जो भी पूंछ-लंबाई की आवश्यकता है उससे भरें। Bleh।

यह कहा जाता है कि, पाइप से "हर कुछ मिनट" पढ़ने का सबसे अच्छा तरीका हर कुछ सेकंड से पढ़ना है।

+1

* में कुछ संकेत मिल सकते हैं * हर कुछ सेकंड से इसे पढ़ें * - यह विशेष रूप से सच है यदि आपका आदेश बहुत अधिक उत्पादन उत्पन्न करता है। पाइप और सॉकेट पर डिफ़ॉल्ट बफर आकार काफी छोटा हो सकता है, और जब पाइप पर लिखने के लिए और अधिक जगह नहीं है तो कमांड अवरुद्ध हो जाएगा। – mob

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