2017-12-18 11 views
1

私は正常に使用しています IO::Tee メッセージをstdoutとログファイルの両方に出力します。私はまた、stdoutとstderrをsystem()コマンドから同じファイルにキャプチャしてteeしたいと思っています。 perlでは、system()がvalを返すためにstdoutとファイルに出力する方法を教えてください。

はノー運

簡単なスクリプト数コメントアウト失敗witha ...

#!/usr/bin/env perl 

use IO:Tee; 

my $teelog = "tee.log" 
open my $tee, ">", $teelog or die "open tee failed.\n"; 
my $tee = new IO:Tee(\*STDOUT, $tee); 

print $tee "First line in log\n"; 

# This command should work. I want the date to go to screen and tee.log 
#system("date | tee -a ${teelog}"); <- nothing goes to tee.log 
#system("date >& ${teelog}") <- clobbers tee.log 
#system("date >& $tee") <- generates syntax errors 


# This command should fail. I want error msg to go to screen and tee.log 
#system("jibberish | tee -a ${teelog}"); <- nothing goes to tee.log 
#system("jibberish >& ${teelog}") <- clobbers tee.log 
system("kibberish >& $tee") <- generates syntax errors 

print $tee "Last line in log\n"; 

exit; 
+1

'$'は '$ system'の入力ミスですか? – toolic

答えて

1

Perlは$teeファイルハンドルへの出力をバッファリングされ、カーソルでリダイレクションおよび/またはパイプの様々な組み合わせを試してみました同じファイルに書き込みを行うsystem呼び出しを実行した後に、$teeの位置が調整されないため、system呼び出しがファイルに書き込む出力をPerlが上書きしている可能性があります。

このような一連の呼び出しはより安全です。あなたはもっと賢明なシークと洗い流しによってより簡潔になることができます。

use IO:Tee; 
my $teelog = "tee.log" 
open my $tee, ">", $teelog or die "open tee failed.\n"; 
$tee = new IO:Tee(\*STDOUT, $tee); 
print $tee "First line in log\n"; 
close $tee; 

system("date | tee -a ${teelog}"); 
system("jibberish 2>&1 | tee -a ${teelog}"); 

open $tee, ">>", $teelog or die "open tee failed.\n"; # append mode 
$tee = new IO:Tee(\*STDOUT, $tee); 

print $tee "Last line in log\n"; 

exit; 
+0

この説明と提案のためにmobに感謝します。 また、IOでcapture_execを使用する別の方法が見つかりました:CaptureOutput。私は次のようなサブでテストしました.... sub tee_sys_cmd { (my $ cmd)= @_; print $ tee "Executing ... \" $ cmd \ "\ n"; my($ stdout、$ stderr、$ success、$ exit_code)= capture_exec($ cmd); \t print $ tee "$ stdout \ n $ stderr \ n"; return; } これも機能するようです。 – daveg

-1

あなたはsystemによって返されるステータスを破棄しているので、私は代わりにバッククォートを使用します。

print $tee `date` 
0

はあなたにこの説明および提案のための暴徒をありがとうございます。

また、IOにcapture_execを使用する別の方法が見つかりました:CaptureOutput。私はこのように見えるサブでテストしました....

sub tee_sys_cmd { 
    (my $cmd) = @_; 

    print $tee "Executing... \"$cmd\"\n"; 
    my ($stdout, $stderr, $success, $exit_code) = capture_exec($cmd); 
print $tee "$stdout\n$stderr\n"; 

    return; 
} 

これもうまくいくようです。

関連する問題