假設我們有:有沒有辦法將一個子程序的打印輸出捕獲到一個變量,所以我可以將它發送到stderr呢?
sub test {
print "testing\n";
}
如果有,我想把它打印到標準錯誤而不是標準輸出的情況下,有沒有辦法,我可以調用子程序來做到這一點?或者我可以捕獲輸出到一個變量,然後使用警告?我對perl相當陌生。
假設我們有:有沒有辦法將一個子程序的打印輸出捕獲到一個變量,所以我可以將它發送到stderr呢?
sub test {
print "testing\n";
}
如果有,我想把它打印到標準錯誤而不是標準輸出的情況下,有沒有辦法,我可以調用子程序來做到這一點?或者我可以捕獲輸出到一個變量,然後使用警告?我對perl相當陌生。
是的。 print
將其輸出發送到「選定」文件句柄,該文件句柄通常爲STDOUT
。但Perl提供了select
函數供您更改。
select(STDERR);
&test; # send output to STDERR
select(STDOUT); # restore default output handle
的select
函數返回先前選定的文件句柄,這樣你就可以抓住它並在以後恢復它。
my $orig_select = select(STDERR);
&test;
select($orig_select);
Perl的通過local()動態作用域不經常使用,但是這在我看來是因爲它具有良好的應用:
test(); # to stdout
{
open(local *STDOUT, ">&STDERR") or die "dup out to err: $!";
test(); # to stderr, locally calling it "STDOUT"
}
test(); # to stdout again
在上面的塊test()
調用 - 以及任何東西test()
本身可能會調用 - 將STDOUT動態限定爲您的STDERR副本。當控制離開塊,即使通過die()
ING,STDOUT將恢復到不管它是塊
廣義前:
sub out2err(&) {
my $user_block = shift;
open(local *STDOUT, ">&STDERR") or die $!;
$user_block->();
}
test(); # to stdout
out2err { test() }; # to stderr
test(); # to stdout
+1即使給定函數顯式地打印到「STDOUT」,這也是可行的。 – chepner
同時,你也可以「捕獲子程序的打印輸出變量「。
只是傳遞一個標量裁判open
:
#! /usr/bin/env perl
use common::sense;
use autodie;
sub tostring (&) {
my $s;
open local *STDOUT, '>', \$s;
shift->();
$s
}
sub fake {
say 'lalala';
say 'more stuff';
say 1 + 1, ' = 2';
say for @_;
}
for (tostring { fake(1, 2, 3) }) {
s/\n/\\n/g;
say "Captured as string: >>>$_<<<";
}
輸出:
Captured as string: >>>lalala\nmore stuff\n2 = 2\n1\n2\n3\n<<<
+1注意,在測試(致命異常)會留下一個非標準FILEHANDLE選擇()d,這是爲什麼我在本地回答下面的答案。 – pilcrow