我想创建一个快速脚本,如果给出文件则写入文件,如果没有给出文件则写入stdout。如果我可以通过将新文件句柄OUTFILE指向适当的任何一个来启动脚本,那么这样做会容易得多。
我知道我可以通过在适当的时候将STDOUT指向我的输出文件来完成我想要的工作,但我宁愿不这样做,因为我不想让以后使用该脚本的任何人感到困惑,并想知道为什么他们的打印声明不要不行。此外,我仍然希望自己偶尔使用打印声明进行故障排除,并且永远不要将此打印输出到输出文件。
所有这些都说,我正在寻找的是:
open( OUTFILE, ($output ? ">$output" : STDOUT );
除了不起作用。
想法?
答案 0 :(得分:37)
某些方式(globs):
# 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);
}
答案 1 :(得分:10)
为了读者的缘故(因为OP已经“开始工作”):
Perl文档,“perlopentut”(perldoc perlopentut)给出了打开一个指向STDOUT的备用文件句柄的示例,但它使用了裸字文件句柄和open
的两个arg版本,两者都有点古老。 Damian Conway的书“Perl Best Practices”(以及Perl :: Critic,基于Damian的书)强调使用三个arg打开和词法文件句柄(my $foo
样式文件句柄)。 chromatic的“Modern Perl”也简要提到了使用词法文件句柄,并且在实际可行的情况下不鼓励使用。三个arg open
被认为是一种更安全的形式,因为它限制了外壳注射的暴露。虽然这里的具体案例风险较低,但默认为3-arg open
仍然是一个好习惯。
仔细阅读Perl的open
文档(perldoc -f open)中显示的示例,并稍微解释一下,在打开指向{{1}的重复的手柄时,注意到&符号的正确位置当使用STDOUT
的三个arg版本时。有人可能会错误地认为这应该有效:open
,主要是因为它看起来像我们习惯看到的格式(符号名称前面的符号)。但是这种语法不是open my $fh, '>', '&STDOUT' or die $!;
所需要的,我们习惯于在完全不同的上下文中看到它:某些子例程调用。
使用三个arg open
向STDOUT
打开欺骗的正确方法是将open
和>
合并到同一个参数中,并保留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
作为对typeglob的引用:
open
答案 2 :(得分:7)
-
很神奇。遵循惯例或违反最少惊喜的原则。
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
相关:Are there reasons to ever use the two-argument form of open(...) in Perl?
答案 3 :(得分:4)
没关系。弄清楚了。投入一个&符可以解决问题。完整的工作代码是:
open( OUTPUT, ( $output ? ">$output" : ">&STDOUT" ) );
答案 4 :(得分:3)
您可以随时将常规输出写入STDOUT
,将调试语句写入STDERR
。然后,如果用户希望输出转到文件,他们只需将STDOUT重定向到命令行上的文件。