Re: [問題] 請教如何實現下邊這種重定向﹖

看板Perl作者 (What?)時間14年前 (2011/05/15 18:52), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串4/4 (看更多)
※ 引述《herolee (hero)》之銘言: : ※ 引述《frank1983 (What?)》之銘言: : : 您可以使用 open STDERR, ">&STDOUT" : : (請參考 http://perldoc.perl.org/functions/open.html ) : : CPAN 上有一些 module 可以試試: File::Tee (不能在 Windows 上執行)、Tee、 : : IO::CaptureOutput 等 : : 這些 module 都能將如 system() 的輸出也導到檔案 (跟 tee 的功能相同) : : 如果您只是想將 print、printf、syswrite 等輸出的結果同時導到檔案,而忽略 : : system() 等由子行程輸出的結果 (這可能需要透過 IPC) : : 則可以考慮使用 IO::Tee : : 您甚至可以自己利用 tie 實作一簡單的多工輸出的 file handle (事實上 IO::Tee 就是 : : 用 tie 實作的) : : Tee.pm 的內容為: : : #!/usr/bin/perl : : use warnings; : : use strict; : : package Tee; : : sub TIEHANDLE { : : my $class = shift; : : my @fh = @_; : : bless \@fh, $class; : : } : : sub WRITE { : : my $this = shift; : : syswrite $_, @_ for @$this; : : } : : sub PRINT { : : my $this = shift; : : print {$_} @_ for @$this; : : } : : sub PRINTF { : : my $this = shift; : : printf {$_} @_ for @$this; : : } : : 1; : : 而主程式為: : : #!/usr/bin/perl : : use warnings; : : use strict; : : use Tee; : : open my $log, '>', 'log.txt' or die; : : tie *FH, 'Tee', \*STDOUT, $log; : : select(*FH); : : print "hello world!\n"; : 如前所述﹐還有兩點不明﹐希望指點。 : 1、這個例子並沒有重定向STDERR﹐有辦法收集到STDERR的東東麼。 : 另外諸如die "Error:$!"這種有沒有辦法實現最初的設想﹐類似2>&1 |tee這種效果。 其實 select(*FH) 的作用就是將 FH 做為 write 和 print 預設的 file handle 所以 print "hello world!" 會將 "hello world!" 輸出至 FH 但是 print STDOUT "hello world!" 或 print STDERR "hello world!" 其實還是會將 "hello world!" 直接輸出至 STDOUT 和 STDERR 而不會透過 FH 如果想收集 die "Error: $!",你也許可以定義 $SIG{__DIE__} 這個 signal handler local $SIG{__DIE__} = sub { print {$log} @_; }; 請參考: 1. http://perldoc.perl.org/functions/select.html 2. http://perldoc.perl.org/functions/die.html : 2、系統調用比如 `ls -l. `之類不能達到上述效果。 : 可以通過print $tee `ls -l .`;來實現﹐但是這樣的效果是屏幕輸出不及時。 : 得等系統命令執行完畢後﹐才能打印輸出。這對於一些執行時間較長的命令﹐ : 效果很不好。 : : 這時 "hello world!\n" 會同時輸出到 STDOUT 和檔案 log.txt : : (請參考 http://perldoc.perl.org/perltie.html#Tying-FileHandles ) print $tee `ls -l .`; 不太可能實現即時輸出 畢竟它就是將 `ls -l` 的結果先存下來再輸出至 $tee 你如果想實現即時輸出可能需要使用 IPC 你可以參考 http://perldoc.perl.org/perlipc.html#Using-open%28%29-for-IPC 當然,最簡單且比較不容易出錯的方式還是使用現成的套件: 如之前提到的 1. File::Tee : http://search.cpan.org/dist/File-Tee/ 2. Tee : http://search.cpan.org/dist/Tee/ 3. IO::CaptureOutput : http://search.cpan.org/dist/IO-CaptureOutput/ 這些套件應該都能符合你的要求 如果我有任何理解錯誤也希望大大們能給予指教~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.243.162.213
文章代碼(AID): #1Dpx1XXA (Perl)
文章代碼(AID): #1Dpx1XXA (Perl)