Perl模糊的命令行选项,以及使用-i的eval的安全含义?
我知道这是不正确的.我只是想知道perl如何解析它.
所以,我正在玩perl,我想要的是perl -ne我输入的是perl – 我的行为很有趣,我想知道发生了什么. $echo 1 | perl -ie'next unless /g/i' 所以perl Aborted(核心倾销)就此.阅读perl –help我看到-i需要一个备份扩展. -i[extension] edit <> files in place (makes backup if extension supplied) 对于那些不知道的人来说 – 只是eval.所以我想三件事中的一件可能发生了,或者被解析为 > perl -i -e’next除非/ g / i’我得到undef,其余的作为参数e 我跑的时候 $echo 1 | perl -i -e'next unless /g/i' 该计划不会中止.这让我相信’下一个除非/ g / i’没有被解析为-e的文字参数.毫不含糊地将上述方法解析,并且它具有不同的结果. 那是什么?好好玩一点,我得到了 $echo 1 | perl -ie'foo bar' Unrecognized switch: -bar (-h will show valid options). $echo 1 | perl -ie'foo w w w' ... works fine guess it reads it as `perl -ie'foo' -w -w -w` 玩弄以上,我试试这个…… $echo 1 | perl -ie'foo e eval q[warn "bar"]' bar at (eval 1) line 1. 现在我真的很困惑..那么Perl如何解析这个呢?最后,似乎你实际上可以从-i中获得Perl eval命令.这有安全隐患吗? $perl -i'foo e eval "warn q[bar]" ' 解决方法
快速回答
Shell报价处理正在崩溃并连接它认为是一个论点.你的调用相当于 $perl '-ienext unless /g/i' 它立即中止,因为perl将此参数解析为包含-u,这会触发核心转储,从而开始执行代码.这是一个曾经用于创建伪可执行文件的旧功能,但它现在在性质上是退化的. 似乎是对eval的调用是对-e’s / g / i的误解. 第一个线索 B::Deparse可以是你的朋友,只要你碰巧在没有 $echo 1 | perl -MO=Deparse,-p -ie'next unless /g/i' dump is not supported. BEGIN { $^I = "enext"; } BEGIN { $/ = "n"; $ = "n"; } LINE: while (defined(($_ = <ARGV>))) { chomp($_); (('ss' / 'g') / 'i'); } 那为什么unle消失了?如果你正在运行Linux,你甚至可能没有达到我的目标.上面的输出来自Cygwin上的Perl,并且关于 下一个线索 值得注意的是perlrun documentation:
工作假设和确认 Perl的参数处理将整个块视为单个选项集,因为它以破折号开头. -i选项使用下一个单词(enext),正如我们在implementation for case 'i': Safefree(PL_inplace); [Cygwin-specific code elided -geb] { const char * const start = ++s; while (*s && !isSPACE(*s)) ++s; PL_inplace = savepvn(start,s - start); } if (*s) { ++s; if (*s == '-') /* Additional switches on #! line. */ s++; } return s; 对于备份文件的扩展名,perl.c上面的代码消耗最多的第一个空格字符或字符串结尾,以先到者为准.如果字符仍然存在,则第一个必须是空格,然后跳过它,如果下一个是破折号,则跳过它.在Perl中,您可以将此逻辑编写为 if ($$s =~ s/i(S+)(?:s-)//) { my $extension = $1; return $extension; } 然后,所有-u,-n,-l和-e都是有效的Perl选项,因此参数处理会占用它们并使其无意义 ss /g/i 作为-e的参数,perl将其解析为一系列分歧.但是在执行甚至开始之前,古老的-u会导致perl转储核心. 意外的行为 更奇怪的是,如果你在next和之间放置两个空格 $perl -ie'next unless /g/i' 程序试图运行. Back in the main option-processing loop我们看到了 case '*': case ' ': while( *s == ' ' ) ++s; if (s[0] == '-') /* Additional switches on #! line. */ return s+1; break; 额外空间终止对该参数的选项解析.见证人: $perl -ie'next nonsense -garbage --foo' -e die Died at -e line 1. 但没有我们看到的额外空间 $perl -ie'next nonsense -garbage --foo' -e die Unrecognized switch: -onsense -garbage --foo (-h will show valid options). 但是,如果有额外的空间和破折号, $perl -ie'next -unless /g/i' dump is not supported. 设计动机 正如评论所指出的那样,逻辑是为了harsh shebang (
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |