-1
for $file ( $ftp -> ls() )
    {
        $bar = file;                

        $dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
        $dst_pattern =~ s/\$\&/\$bar/g;

        $dst_dir1 = eval( $dst_dir );
        $dst_file = eval( $dst_pattern ); 
    }

在 Perl 中,这对 filename 做了什么$bar$bar替换也是如此\$\&,但那是什么?还有什么会评估一个字符串给here

4

3 回答 3

3

看起来它用 '$bar' in 替换了每次出现的 '$&' $foo。这是在数据中实现简单占位符标记语法的典型方法。

的返回值eval是将 的值$foo视为 Perl 源代码的结果。假设正常执行,eval将返回最后一个计算的表达式$foo(或者return如果执行一个语句的参数)。请注意,评估$foo也可能有副作用(I/O、变量分配等)。如果不知道要从什么$foo开始,就不可能说更多。

于 2013-07-30T15:36:58.183 回答
0

很难给你一个全面的答案,因为我们不知道嵌入代码片段的代码的最高目标。特别是关于$foo和中的内容$bar

尽管如此,我还是写了一个小脚本来说明特定的替换和以下eval语句:

#!/usr/bin/env perl 

$bar = "10";
$foo = '10*$&';

print 'content of `$bar`: ', $bar, "\n";
print 'content of `$foo` befor substitution: "', $foo, "\"\n";

$foo =~ s/\$\&/\$bar/g;

print 'content of `$foo` after substitution: "', $foo, "\"\n";

$a = eval($foo);

print 'result of the evaluation: ', $a, "\n";

脚本的输出是:

content of `$bar`: 10
content of `$foo` befor substitution: "10*$&"
content of `$foo` after substitution: "10*$bar"
result of the evaluation: 100

结束eval语句评估 is 的内容,就$foo好像"10*$bar"它是一个正则 perl 表达式。因此你可以想到这条线

$a = eval($foo);

作为

$a = 10*$bar;

因此该值100存储在$a.

于 2013-07-30T16:14:03.763 回答
0

我注意到一件事...

for $file ( $ftp -> ls() )
{
    $bar = file;

这应该是$bar = $file而不是$bar = file(您的脚本缺少前导$file。否则,您只是将字符串file放入$bar.

你表达的另一部分是:

$dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
$dst_pattern =~ s/\$\&/\$bar/g;

$dst_dir和的值是$dst_pattern多少?这才是真正的问题。

某处$dst_dir并且$dst_pattern正在被设置。这是您将 FTP 中的文件替换为这些字符串的地方。然后我注意到这一点:

$dst_dir1 = eval( $dst_dir );
$dst_file = eval( $dst_pattern ); 

似乎是$dst_dir某种$dst_file命令?为什么还要eval在它们上面运行?这两个字符串的值是多少?为什么要通过 运行它们eval

发生的事情是这两个命令中包含字符串$&,并且您正在用您正在 ftp'​​ing 的文件替换该字符串。

假设$dst_dir等于$ftp->get("$&")。您从$ftp->ls命令中获得的文件名(假设它bar.txt被替换为该字符串。因此,$dst_dir1设置为$ftp->get("bar.txt");.

并查看整个循环:

for $file ( $ftp -> ls() )
{
    $bar = file;                

    $dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
    $dst_pattern =~ s/\$\&/\$bar/g;

    $dst_dir1 = eval( $dst_dir );
    $dst_file = eval( $dst_pattern ); 
}

我看到另一个问题。您正在遍历每个文件并每次都替换$&in 。但是,如果您对每个文件都执行此操作,并且您没有重置and的原始值。这意味着您第二次通过循环时,您不会更改and 。而且,在所有其他时间里,你也会经历你的循环。$dst_dir$dst_pattern$dst_dir$dst_pattern$dst_dir$dst_pattern

您也没有检查以确保替换确实有效,并且您没有eval通过检查$@.

最重要的是,您没有设置use strict;,也可能没有use warnings;

这是循环的新版本:

for my $file ( $ftp->ls ) {
    my $dist_dir     = $dst_dir;      # Make sure you don't futz with your
    my $dist_pattern = $dst_pattern;  # original templates!

    # Check to make sure replacements work!
    if ( not $dist_dir =~ s/\$\&/\$file/g ) {
       die qq(Couldn't put file name "$file" into "$dist_dir");
    }
    if ( not $dist_pattern =~ s/\$\&/\$file/g ) {
       die qq(Couldn't put file name "$file" into "$dist_pattern");
    }

    # Check for Eval!
    my $dst_dir1;
    my $dst_file1;
    $dst_dir1 = eval( $dist_dir );
    if ( "$@" ) {
       die qq(Evaluation of `$dist_dir` failed!: $@ );
    }

    $dst_file1 = eval( $dist_pattern );
    if ( "$@" ) {
      die qq(Evaluation of '$dist_pattern' failed!: $@);
    }
}

这是检查以确保替换有效,并且还可以节省每次都修改模板。

于 2013-07-30T17:26:20.253 回答