perl脚本中的重定向
2013-10-07 15:06:20 阿炯

本站赞助商链接,请多关照。 最简单的文件操作是'open'函数,默认有三种文件句柄:STDIN,STDOUT,STDERR。

后两者是输出句柄,我们可以将它进行重定向。
open STDOUT, '>', "foo.out";
open STDOUT,">> foo.out" or die "cat not open foo.out";

The child itself can do select $filehandle to specify that all of its print calls should be directed to a specific filehandle.

The best the parent can do is use system or exec or something of the sort to do shell redirection.

示例如下:
print "to console\n";
open OUTPUT, '>', "foo.txt" or die "Can't create filehandle: $!";
select OUTPUT; $| = 1;  # make unbuffered
print "to file\n";
print OUTPUT "also to file\n";
print STDOUT "to console\n";
# close current output file
close(OUTPUT);
# reset stdout to be the default file handle
select STDOUT;
print "to console";

open my $fh, '>', $file;
defined(my $pid = fork) or die "fork: $!";
if (!$pid) {
 open STDOUT, '>&', $fh;
 # do whatever you want
 ...
 exit;
}
waitpid $pid,0;
print $? == 0 ? "ok\n" : "nok\n";

如果指定了重定向文件,将输出定向到其
use autodie qw(:all);
open(OUTPUT,($output ? ">$output" : ">&STDOUT"));

open FILE, ">$file";
select FILE; # print will use FILE instead of STDOUT
print "Hello, world!"; # goes to FILE
select STDOUT; # back to normal
print "Goodbye."; # goes to STDOUT

三参数的形式就只读文件句柄而言,管理符号写在了命令占位符的后边;亦指文件句柄打开模式,只读文件句柄应用'-|';如果需要只写句柄就用'|-','-'类似于要执行的 命令在管道传递中的位置。

#使用系统的find指令查看某目录那些90天未被存取过,占用空间超过1000块的文件。
#在find工作时,perl会等待:每找到一个文件,perl会对每个传入的文件名作出进一步响应并其信息。
open my $fh4find,'-|','find',qw(/home/hto/soft -atime +90 -size +1000 -print) or die "fork for find failed by:$!";

while(<$fh4find>){
    chomp;
    printf "%s,size %dK last access %.2f days ago.\n",$_,(1023+-s $_)/1024,-A $_;
}

#如果用反引号(``)调用find的话,就得等到find彻底完成后才看到第一行输出。

------------------------------
perl的三通指令,像shell中的'tee'指令
$ perl -le 'print "Hello, world"' | tee /tmp/h.log

To set up this duplication from within your program, set up a pipe from your STDOUT to an external tee process. Passing "|-" to open makes this easy to do.

#!/usr/bin/env perl
my @copies = qw( /tmp/foo.log /tmp/bar.log );
open STDOUT, "|-", "tee", @copies or die "$0: tee failed: $!";
print "Hello, world!\n";

close STDOUT or warn "$0: close: $!";

使用IO::Tee

use IO::Tee;
open(my $fh1,">","tee1.log") or die $!;
open(my $fh2,">","tee2.log") or die $!;

my $tee=IO::Tee->new($fh1,$fh2);

select $tee; #This makes $tee the default handle.

print "FreeOA!\n";

使用File::Tee

use File::Tee qw(tee);
tee(STDOUT, '>', 'stdout.txt');

# simple usage:
tee(STDOUT, '>', 'stdout.txt');

print "hello world\n";
system "ls";

# advanced usage:
my $pid = tee STDERR, { prefix => "err[$$]: ", reopen => 'my.log'};

print STDERR "foo\n";
system("cat /bad/path");