perl脚本中的重定向
最简单的文件操作是'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");