如何修复 perl eval() 中的“Bareword found”问题

How to fix 'Bareword found' issue in perl eval()

提问人:yasara malshan 提问时间:10/22/2021 最后编辑:zdimyasara malshan 更新时间:3/24/2022 访问量:231

问:

以下代码返回“Bareword found where operator expected at (eval 1) line 1, near ”*,out“ (Missing operator before out?)”

$val = 0;
$name = "abc";
$myStr = '$val = ($name =~ in.*,out [)';
eval($myStr);

根据我的理解,我可以通过用“//”包装“in.*,out [”块来解决这个问题。

但是“in.*,out [”可以是变化的。(例如:用户输入)。因此,有没有其他方法可以处理这个问题。?(例如:如果 eval() 试图返回“Bareword found where ...”,则返回 0)

正则表达式 Perl 评估

评论

3赞 zdim 10/22/2021
请注意,“字符串”通常是一个糟糕的主意,而且dddangerous。它允许任意代码运行;即使没有任何可能严重破坏事情的不良意图。确定没有其他办法吗?几乎总是有。eval
1赞 zdim 10/22/2021
您显示的错误消息意味着您正在运行该(危险)代码而未启用警告?(会有不同的消息。总而言之,这只是自找麻烦。只是一个善意的警告。use warnings;
1赞 Dave Mitchell 10/22/2021
你在那里使用 eval 的目的是什么?
0赞 yasara malshan 10/26/2021
目的是执行$myStr。[ 我有一个给定的模式(在这里,它是“in.*,out [”),我正在与$name进行正则表达式匹配。之后,我将结果存储在$val中。
0赞 zdim 11/5/2021
@yasaramalshan “目的是执行$myStr”——问题是,你为什么需要这样做?似乎您可以拥有普通代码,当您接受用户的输入时(可能在程序的前面)将其分配给 。你为什么不能这样做呢?my $val = ($name =~ /$input/);$input

答:

6赞 zdim 10/22/2021 #1

(字符串)eval 的魔力和危险在于,它将一堆虚拟字符转换为代码,编译并运行它。那么可以使用吗?嗯,不,当然,当该字符串被视为代码时,它就是一个松散的逗号运算符,一个语法错误;和一个“赤裸裸的词”.该字符串必须生成有效的代码'$x = ,hi'hi

在字符串求值中,表达式的值(它本身是在标量上下文中确定的)首先被解析,如果没有错误,则在当前 Perl 程序的词法上下文中作为块执行。

因此,问题中的字符串将只是(严重)无效的代码,不会编译,句号。如果字符串的一部分在某种引号中,那么这是合法的,=~ 运算符会将其视为一种模式,并且您有一个正则表达式。但是,当然为什么不使用正则表达式的正常模式分隔符,例如(或等)。in.*,out [//m{}

无论以何种方式获取该字符串,它都将位于变量中,不是吗?因此,您可以事先将其填充。/$input/eval$input

但是,最重要的是,你确定没有其他办法吗?总是有的。字符串 - 复杂而棘手,难以正确使用,几乎不可能证明 - 而且很危险。它运行任意代码!即使没有任何不良意图,也会严重破坏事情。eval

我强烈建议考虑其他解决方案。此外,目前还不清楚为什么首先需要 - 因为你只需要正则表达式模式作为用户输入(而不是代码),你可以在普通代码中拥有非常正则表达式,并在变量中有一个模式,该模式在提供用户输入时会更早填充。(请注意,从用户那里获取模式也可能导致麻烦。eval


如果你喜欢,这是一个问题,我们都是。warnings

2赞 ikegami 10/22/2021 #2

以下代码无效:

$val = ($name =~ in.*,out [)

您需要满足以下条件:

$val = $name =~ /in.*,out \[/

(parens 无害,但也没有帮助。

如果模式是用户提供的,则可以使用以下命令:

$val = $name =~ /$pattern/

(不需要!eval EXPR

请注意,更正中的模式不正确。您可以使用以下命令捕获此类错误eval BLOCK

eval { $val = $name =~ /$pattern/ };
die("Bad pattern \"$pattern\" provided: $@") if $@;

关于用户提供的模式的说明:上面的内容不会允许用户执行任意代码,但它不会保护你免受需要比宇宙寿命更长的模式的伤害。