perl eval的问题

时间:2015-09-20 07:13:29

标签: perl eval

我有以下代码,它会通过从文件中读取来设置$mystring的值。

#!/usr/bin/perl

use warnings;
use strict;

use Data::Dumper;

my $mystring1 = "vault.\$_[0].org/\$_[1].\$_[2]/os/\$_[4]";
my $mystring2 = "vault.$_[0].org/$_[1].$_[2]/os/$_[4]";

&myfunc ("A1", "b2", "C3", "d4");

sub myfunc {

    print Dumper(\@_);

    print ("Before=$mystring1\n");
    my $test = eval($mystring1);
    print ("test=$test\n");

    print ("Before=$mystring2\n");
    $test = eval($mystring2);
    print ("test=$test\n");
}

但是会产生以下输出:

Use of uninitialized value $_[0] in concatenation (.) or string at ./t.pl line 7.  
Use of uninitialized value in concatenation (.) or string at ./t.pl line 7.  
Use of uninitialized value in concatenation (.) or string at ./t.pl line 7.  
Use of uninitialized value in concatenation (.) or string at ./t.pl line 7.  
$VAR1 = [  
          'A1',  
          'b2',  
          'C3',  
          'd4'  
        ];  
Before=vault.$_[0].org/$_[1].$_[2]/os/$_[4]  
Use of uninitialized value $test in concatenation (.) or string at ./t.pl line 15.  
test=  
Before=vault..org/./os/  
Use of uninitialized value $test in concatenation (.) or string at ./t.pl line 18.  
test=  

导致问题的原因是什么?如何实现以下目标?

test=vault.A1.org/b2.C3/os/d4

我如何使用eval或创建子程序来实现此功能?

1 个答案:

答案 0 :(得分:5)

我不会使用eval。一般来说,除非绝对必要,否则应该避免由于与之相关的安全隐患。在你的情况下,你说的话可能是一个坏主意

  

mystring的值在

中读取的文件中设置

这意味着您的eval来电可以执行任意用户输入... 糟糕的想法!

为什么不使用sprintf

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

my $mystring1="vault.%s.org/%s.%s/os/%s";

myfunc ("A1", "b2", "C3", "d4");

sub myfunc {
    print Dumper(\@_);
    my $test = sprintf $mystring1, @_;
    print ("test=$test\n");
}

一个简单的解决方案,可以满足您的所有需求。