对于我正在尝试用perl编写的程序,我想构建一个使输出转到输出文件的选项,这对于perl模块Getopt来说非常简单。但是,如果没有使用该选项,我希望输出转到终端(STDOUT)。因为我写了一个小脚本来测试我是否可以使用模块IO :: File构建一个开关。
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;
use IO::File;
my $outfilename;
GetOptions (
"out=s" => \$outfilename,
);
my $out = IO::File->new(">$outfilename");
if (defined $out) {
print $out "Hello World!\n";
}
else {
print "Hello World!\n";
}
close $out if $outfilename;
虽然该计划"运行"有或没有-o选项,当我在没有-o的情况下运行时,perl告诉我第13行中的$ outfilename未初始化,我猜是因为Getopt将变量返回为" false"何时不使用该选项。但是,我想不出办法绕过这个。你能帮助我吗? 另外,我绝对相信有一种更容易的方法来构建我不知道的这种开关。我只是写这篇文章是因为我无法找到更好的在线方式,所以如果你们有任何关于如何做到更聪明的提示,我将非常感激!
答案 0 :(得分:4)
您收到警告是因为您无条件地使用$outfilename
作为文件名,即使它仅在提供--out
时具有值。
不要将整个print
放在if
中。如果你这样做,你最终会得到大量重复的代码。创建一个在所有条件下初始化的文件句柄
my $outfh;
if (defined($outfilename)) {
open($outfh, '>', $outfilename)
or die($!);
} else {
$outfh = \*STDOUT;
}
print $outfh "Hello World!\n";
或重定向STDOUT
if (defined($outfilename)) {
open(STDOUT, '>', $outfilename)
or die($!);
}
print "Hello World!\n";
但是你为什么不从外面重定向STDOUT?
script >script.log
答案 1 :(得分:4)
您可以使用select
设置默认输出文件句柄。这将使print
自动打印到select
ed文件句柄。
if ($outfilename) {
open my $outfh, ">", $outfilename
or die "Cannot open $outfilename for output: $!";
select $outfh;
}
print "Hello world!\n";
答案 2 :(得分:0)
您可以用文件句柄替换STDOUT,然后正常打印。
if($outfilename) {
open my $of, ">", $outfilename;
*STDOUT = $of;
}
print "Hello World!\n";
答案 3 :(得分:-1)
你最好看看以下内容:
select
调用可让您重新定义print
调用的默认文件处理程序。
SelectSaver
允许您在给定代码块的范围内执行相同的操作。
在您的情况下,您可以重写代码,以便在运行将执行输出的代码之前,根据需要创建输出文件句柄并select
。反过来,输出代码只会在没有文件句柄的情况下调用print
。