无法将系统命令的输出重定向到名为error.log的文件,将stderr重定向到另一个名为test_file.errorlog的文件

时间:2015-09-02 13:30:22

标签: perl

这个perl脚本遍历所有目录和子目录,在其中搜索名为RUN的文件。然后它打开文件并运行文件中写入的第一行。问题是我无法将系统命令的输出重定向到名为error.logSTDERR的文件到另一个名为test_file.errorlog的文件,但是没有创建这样的文件。

请注意,如果找不到,则声明所有变量。

find (\&pickup_run,$path_to_search);

### Subroutine for extracting path of directories with RUN FILE PRESENT
sub pickup_run {
    if ($File::Find::name =~/RUN/) {
        ### If RUN file is present , push it into array named run_file_present
        push(@run_file_present,$File::Find::name);
    }
}

###### Iterate over the array containing paths to directories containing RUN files one by one 
foreach my $var (@run_file_present) {
    $var =~ s/\//\\/g;
    ($path_minus_run=$var) =~ s/RUN\b//;
    #print "$path_minus_run\n";

    my $test_case_name;
    ($test_case_name=$path_minus_run) =~ s/expression to be replced//g;

    chdir "$path_minus_run";
    ########While iterating over the paths, open each file
    open data, "$var";

    #####Run the first two lines containing commands 
    my @lines = <data>;

    my $return_code=system (" $lines[0] >error.log 2>test_file.errorlog");
    if($return_code) {
        print "$test_case_name \t \t FAIL \n";
    }
    else {
        print "$test_case_name \t \t PASS \n";
    }
    close (data);
}

1 个答案:

答案 0 :(得分:1)

问题几乎可以肯定$lines[0]在从文件中读取后有一个换行符

但是你可以做出一些改进

  • 始终use strictuse warnings位于每个Perl程序的顶部,并使用my尽可能接近第一个使用点声明所有变量

  • 使用三参数形式的open 并始终检查是否成功,将内置变量$!放入die字符串说为什么它失败了。您还可以use autodie为每次打开手动保存为此编写代码,但它需要Perl v5.10.1或更高版本

  • 你不应该在标量变量周围加上引号 - 只是按原样使用它们。所以chdir $path_minus_runopen data, $var是正确的

也无需保存要处理的所有文件,以后再处理。在wanted子例程中,File::Find设置为$File::Find::dir设置为包含该文件的目录,$_设置为没有路径的裸文件名。它还为您的目录执行chdir,因此上下文非常适合处理文件

use strict;
use warnings;
use v5.10.1;
use autodie;

use File::Find;

my $path_to_search;

find( \&pickup_run, $path_to_search );

sub pickup_run {

    return unless -f and $_ eq 'RUN';

    my $cmd = do {
        open my $fh, '<', $_;
        <$fh>;
    };
    chomp $cmd;

    ( my $test_name = $File::Find::dir ) =~ s/expression to be replaced//g;

    my $retcode = system( "$cmd >error.log 2>test_file.errorlog" );

    printf "%s\t\t%s\n", $test_name, $retcode ? 'FAIL' : 'PASS';
}