2013-07-19 58 views
2

我問了下面的以下問題,我發現一個非常接近的答案,但後來意識到它不起作用。我在perl中使用管道。但在我通過管道打到我的狀態之前,該功能已完成運行。有沒有辦法在運行時檢查的非常精確的第二停止過程中一旦10香蕉的傳球用perl中的一個條件停止進程

parse output and count number of times a string appears

你好,我想這...但它不工作...的過程在我甚至沒有機會阻止它之前完成。沒有任何東西可以實際控制pid過程的流程。我的意思是,23只香蕉在發現10個完成之前已經過了。我猜管道流量比實際過程慢

我想要做的就是在已經運行的過程中添加一個延遲。喜歡: 可以說我們知道輸出是什麼樣子: 命令1輸出 命令2輸出 香蕉 現在我可以解析香蕉,並在過程中延遲5秒。一旦我注入延遲,我可以在那段時間運行我的Perl腳本,並及時停止腳本。

爲了清楚我的問題: 代碼中,我寫道:

my $pid = open my $pipe, '-|', 'commandA | tee banana.foo' 
    or die "Error opening pipe from commandA: $!\n"; 
# open my $pipe, 'commandA | tee result |' 
# or die "Error opening pipe from commandA: $!\n"; 
    print "$pid\n"; 
    my $n = 0; 
    while (<$pipe>) { 
    $n++ if /banana/; 
    last if $n > 0; 
    print "pipestring\n"; 
    } 
    kill 'INT', $pid; 
    close $pipe; # kills the command with SIGPIPE if it's not done yet 

    if ($n eq 1) { 

    print "commandA printed 'banana'\n"; 
    } 
    else 
    { 
    print "nothing happened\n"; 
    } 

banana.foo (actual result) | banana.foo (expected result) 
one       | one 
two       | two 
three       | three 
banana       | banana 
four 
five 

所以我不希望最後的2個值,並希望程序停止。 commandA是:

echo one 
echo two 
echo three 
echo banana 
echo four 
echo five 

重要編輯:我想我會朝着創造一個調試器中去。有人擁有任何開源調試器或其他控制進程的其他代碼。

+0

你不顯示你跑的代碼。如果您運行此處顯示的「pipestring」,則會打印3次,然後是「commandA印刷的香蕉」消息。而你的散文似乎指的是甚至沒有暗示的代碼... –

+0

我建議你重新考慮你的方法。一般來說,當進程執行時,你不會有太多的控制,並且必須對操作系統有彈性,給予你處理器時間,當* it *認爲它方便時。 – darch

回答

-2

我在編輯這篇文章,因爲我顯然誤解了你需要的東西。

http://perldoc.perl.org/perlipc.html#Bidirectional-Communication-with-Another-Process

這整個頁面有關於如何有過孩子的過程更多的控制的一些想法,等

+1

請參閱編輯 – ban

+0

他需要控制進程是異步的,因爲他不希望子進程完成。 – darch

+0

我明白了。這裏似乎有一些替代解決方案,因爲看起來他需要其他東西來確定分叉進程在做什麼。 http://perldoc.perl.org/functions/open.html –

1

什麼你試圖做絕不會可靠地工作:總有之間的競爭進程將數據寫入文件,另一個進程試圖將其殺死。由於這兩個進程之間有幾個緩衝階段,因此寫入過程很有可能在死亡之前產生大量額外的輸出。

我能想到的唯一的辦法避免這種情況是:

  1. 移動終止條件檢查正在生產輸出的程序(打印10個「香蕉」 S後停止)。這樣,你根本不需要殺死它。

  2. 打印每一行後有產生輸出的程序等待來自其他程序的某種確認。這是可能的,但相當棘手,可能效率低下。

  3. 而不是使用tee的,有控制程序(即檢查終止條件之一)將數據寫入到輸出文件,像這樣:

    open my $out, '> banana.foo' 
        or die "Error opening banana.foo for writing: $!\n"; 
    
    my $pid = open my $pipe, 'commandA |' 
        or die "Error opening pipe from commandA: $!\n"; 
    
    my $n = 0; 
    while (<$pipe>) { 
        print $out $_; 
        $n++ if /banana/; 
        last if $n > 0; 
    } 
    kill 'INT', $pid; 
    close $pipe; 
    
+0

是的,但我甚至不需要問這個問題。他們可以繼續前進並更改我的原始代碼。 – ban

+0

我想控制來自外部的流量... – ban

+0

上面的選項3,我提供了示例代碼,並不要求您以任何方式更改'commandA'。它不會實際上停止'commandA'產生額外的輸出,但是它會_will_保持輸出結束在文件中。 –