open( OUTFILE, ($output ? ">$output" : STDOUT );
有什么想法吗?
open( OUTFILE, ($output ? ">$output" : STDOUT );
一些方法(通配符):
# Requires 2-arg open, unfortunately
open(OUTPUT, "> ".($output || '-')) or die;
if ($output) {
open(OUTPUT, '>', $output) or die;
} else {
*OUTPUT = *STDOUT;
}
if ($output) {
open(OUTPUT, '>', $output) or die;
} else {
open(OUTPUT, '>&', \*STDOUT) or die;
}
一些方法(词法变量):
# Requires 2-arg open, unfortunately
open(my $fh, "> ".($output || '-')) or die;
my $fh;
if ($output) {
open($fh, '>', $output) or die;
} else {
$fh = \*STDOUT;
}
my $fh;
if ($output) {
open($fh, '>', $output) or die;
} else {
open($fh, '>&', \*STDOUT) or die;
}
其他一些方式:
# Changes the default handle for <print "foo">.
if ($output) {
open(OUTPUT, '>', $output) or die;
select(OUTPUT);
}
为了读者的方便(因为 OP 已经“让它工作了”),Perl 文档“perlopentut”(perldoc perlopentut)提供了打开指向 STDOUT 的备用文件句柄的示例,但它使用裸字文件句柄和两个参数版本的 open
,这两种方法有些古老。Damian Conway 的书籍“Perl Best Practices”(以及基于 Damian 的书的 Perl::Critic)强调使用三个参数的 open 和词法文件句柄(my $foo
风格)。chromatic 的“Modern Perl”也简要提到了使用词法文件句柄,并在实际情况下不鼓励使用裸字。三个参数的 open
被认为是一种更安全的形式,因为它限制了对 shell 注入的曝光。虽然这里的具体情况风险较低,但默认使用三参数的 open
是一个好习惯。
需要仔细阅读 Perl 的 open
文档中显示的示例(perldoc -f open),并稍微解释一下,在使用三个参数版本的 open
打开一个重复的指向 STDOUT
的文件句柄时正确放置 & 符号的位置。人们可能会错误地认为这应该起作用:open my $fh, '>', '&STDOUT' or die $!;
,主要是因为它看起来像我们习惯看到的格式(符号名称前面有一个 & 符号)。但这种语法不是 open
需要的,而且我们习惯在完全不同的上下文中看到它:某些子例程调用。
使用三个参数的 open
打开指向 STDOUT
的重复方式是将 >
和 &
结合到同一个第二个参数中,并将 STDOUT 留空,如下所示:
use Modern::Perl;
open my $fh, '>&', STDOUT or die "Bleah: $!";
say $fh 'Printing alternate filehandle "$fh" worked.';
say 'Implicitly printing to "STDOUT" also works.';
或者将STDOUT
作为类型glob的引用传递给open
:
open my $fh, '>&', \*STDOUT or ...
-
是神奇的符号。遵循惯例,否则你会违反最小惊讶原则。
use autodie qw(:all);
use Getopt::Long qw(GetOptions);
GetOptions(\my %opt, 'out=s') or die 'usage';
die 'usage' unless $opt{out};
open my $handle, ">$opt{out}";
perl foo -o blahblah # opens file blahblah for writing
perl foo -o - # goes to STDOUT
相关: 在Perl中,是否有使用open(...)的两个参数形式的原因?
没事了,我想通了。加上一个&符号就可以了。完整的可用代码如下:
open( OUTPUT, ( $output ? ">$output" : ">&STDOUT" ) );
STDOUT
,将调试语句写入STDERR
。如果用户想要将输出写入文件,他们只需在命令行中将STDOUT重定向到文件即可。scriptname.pl > filename.txt
,这样脚本就会运行并且输出将最终出现在文件 filename.txt
中。任何标准错误(stderr)上的调试代码仍将显示在控制台上。这是大多数*nix实用程序和脚本的工作方式。 - Andrew Cooper
... } else { open($fh, '>&' . fileno(STDOUT)); }
- mob