2016-11-20 31 views
1

我有打印到stdout一個shell腳本(testScript.sh),等待一點點,然後再次打印:Perl如何執行沒有緩衝的shell腳本?

#!/bin/sh 
echo "before" 
sleep 2 
echo "after" 

我試圖從一個Perl腳本,這樣執行這個sh腳本:

#!/usr/bin/perl -w 
use strict; 

$| = 1; # do I need this? 

sub runCommand($) { 
    my ($command) = @_; 
    open CMD, "$command |" || die "Unable to run $command: $!"; 
    my @output = <CMD>; 
    close CMD; 
    print join('',@output); 
} 

runCommand("./testScript.sh"); 

如果我直接運行shell腳本,我立即看到「之前」,然後延遲,然後「之後」。

但是,當我通過perl運行腳本時,首先得到延遲,然後打印「之前」和「之後」。

我在想這是因爲Perl's I/O buffering,但$| = 1似乎沒有任何影響。

我在這裏錯過了什麼?如何通過perl執行腳本並仍然立即寫入stdout

+1

'$ | = 1;'只有* Perl腳本*的輸出被重定向纔會有所作爲,但是沒有提到這一點。 '$ | = 1;因此沒有效果。 – ikegami

+0

@ikegami是正確的,是的,在這個用例中''| = 1;'是不必要的 –

+0

如果子程序確實在緩衝,可以使用僞ttys來試圖欺騙它,使其不緩衝。 IPC :: Run可以使這個變得簡單,'expect'分發中的'unbuffer'實用程序也是如此。 – ikegami

回答

4

您編寫的代碼等待從命令中讀取所有輸入,然後加入並打印它。有沒有辦法,你可以得到一個像從print調用輸出

,因爲它被檢索到,這樣

open CMD, "$command |" || die "Unable to run $command: $!"; 
print while <CMD>; 
close CMD; 

是的,你確實需要$| = 1您必須打印的每一行,否則增量輸出將被緩衝

+0

謝謝,現在有道理 –