【问题标题】:Unable to redirect the output of the system command to a file named error.log and stderr to another file named test_file.errorlog无法将系统命令的输出重定向到名为 error.log 的文件和 stderr 到另一个名为 test_file.errorlog 的文件
【发布时间】:2015-09-02 13:30:22
【问题描述】:

这个 perl 脚本正在遍历所有目录和子目录,在其中搜索一个名为 RUN 的文件。然后它打开文件并运行文件中写入的第一行。问题是我无法将系统命令的输出重定向到名为error.log 的文件和STDERR 到另一个名为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);
}

【问题讨论】:

    标签: perl


    【解决方案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';
    }
    

    【讨论】:

    • 是的,问题确实与 chomp 有关。我将行 [0] 切碎并重定向它,瞧!有效。感谢您的见解和建议。我是 perl 新手,自从 15 天以来一直在使用它。所以我会一路学习!
    猜你喜欢
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 2014-08-05
    • 1970-01-01
    相关资源
    最近更新 更多