Perl:将STDERR重定向到文件而不创建空文件?

Jag*_*616 3 perl file-io io-redirection

我正在使用perl脚本重定向STDOUT和STDERR:

open STDOUT, '>', $logfile or die "Can't redirect STDOUT: $!";
open STDERR, ">&STDOUT" or die "Can't dup for STDERR: $!";
Run Code Online (Sandbox Code Playgroud)

在...之前和之后保存和恢复文件句柄

事实是,如果程序没有输出,我最终得到一个0号文件,但我想根本没有文件.如果不手动检查和删除文件,我怎么能这样做?

谢谢!

Sea*_*ean 5

您可以将STDOUT绑定到延迟打开目标文件的类,直到第一次写入句柄为止:

package FastidiousHandle;

use Tie::StdHandle;
use strict;

our @ISA = 'Tie::StdHandle';

sub TIEHANDLE {
    my ($class, @args) = @_;
    my $self = $class->SUPER::TIEHANDLE;
    ${*$self}{openargs} = \@args;
    return $self;
}

sub WRITE {
    my $self = shift;
    my $openargs = delete ${*$self}{openargs};
    $self->OPEN(@$openargs) if $openargs;
    $self->SUPER::WRITE(@_);
}

1;
Run Code Online (Sandbox Code Playgroud)

然后在你的主程序中,你会说:

tie *STDOUT, 'FastidiousHandle', '>', $path;
my $saved_stderr = *STDERR;
*STDERR = *STDOUT;
Run Code Online (Sandbox Code Playgroud)

要恢复以前的句柄,你会说:

*STDERR = $saved_stderr;
untie *STDOUT;
Run Code Online (Sandbox Code Playgroud)


unp*_*nic 5

如果有任何内容,请在结尾处检查,如果没有,请删除该文件.确保你有autoflush.

use IO::Handle;
...
open STDOUT, '>', $logfile or die "Can't redirect STDOUT: $!";
open STDERR, ">&STDOUT" or die "Can't dup for STDERR: $!";

STDOUT->autoflush(1);
STDERR->autoflush(1);

...

END {
    unlink $logfile if -z $logfile;
}
Run Code Online (Sandbox Code Playgroud)

或者旧式......

open STDOUT, '>', $logfile or die "Can't redirect STDOUT: $!";
open STDERR, ">&STDOUT" or die "Can't dup for STDERR: $!";
select(STDERR); $|=1; select(STDOUT); $|=1;

END {
    unlink $logfile if -z $logfile;
}
Run Code Online (Sandbox Code Playgroud)