加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

解释Perl“前导”的瑕疵

发布时间:2020-12-15 21:23:01 所属栏目:大数据 来源:网络整理
导读:Perl手册描述了一个完全迂回的构造,可以在任何csh,sh或Perl下工作,如下所示: eval '(exit $?0)' eval 'exec perl -wS $0 ${1+"$@"}' eval 'exec /usr/bin/perl -wS $0 $argv:q' if $running_under_some_shell; 呃真的吗?有人可以详细解释一下这个工作吗?
Perl手册描述了一个完全迂回的构造,可以在任何csh,sh或Perl下工作,如下所示:
eval '(exit $?0)' && eval 'exec perl -wS $0 ${1+"$@"}'
    & eval 'exec /usr/bin/perl -wS $0 $argv:q'
    if $running_under_some_shell;

呃真的吗?有人可以详细解释一下这个工作吗?

解决方法

这个想法是,如果它们在标准的Bourne shell(sh),C shell(csh)或Perl中进行评估,那么这三行可以做3种不同的事情.只有在不支持使用#指定解释器名称的系统上才需要这个黑客攻击!在脚本开始的行.如果您执行Perl脚本以这3行作为shell脚本开始,shell将启动Perl解释器,传递脚本的文件名和命令行参数.

在Perl中,三行形成一个声明,以…的形式终止

eval '...' && eval '...' & eval '...' if $running_under_some_shell;

由于脚本刚刚启动,$running_under_some_shell是undef,它是false,并且永远不会执行evals.这是一个不起眼的

狡猾的部分是在sh与csh中解析$?0不同.在sh,那意味着$? (最后一个命令的退出状态)后跟0.由于没有以前的命令,$?将为0,所以$?0计算为00.在csh中,$?0是一个特殊变量,如果当前输入文件名已知,则为1,如果不是,则为0.由于shell从脚本中读取这些行,所以$?0将为1.

因此,在sh中,eval'(exit $?0)’表示eval'(exit 00)’,而在csh中它表示eval'(exit 1)’.括号表示exit命令应该在subshel??l中进行求值.

sh和csh都了解&&意思是“执行上一个命令,然后只有当前一个命令退出0”时才执行以下命令.所以只有sh将执行eval’exec perl -wS $0 ${1“$@”}’. csh将进入下一行.

csh将在行的开头忽略“&”. (我不知道这是什么意思csh,其目的是使这个从Perl的角度来看是一个单一的表达式)csh然后继续评估eval’exec /usr/bin/perl -wS $0 $argv:q ”.

这两条命令行非常相似. exec perl意味着通过启动perl的副本来替换当前进程. -wS与-w(启用警告)和-S(在$PATH中查找指定的脚本)相同. $0是脚本的文件名.最后,${1“$@”}和$argv:q产生当前命令行参数的副本(分别为sh和csh).

它使用${1“$@”}而不是更常见的“$@”来解决一些古老版本的Bourne shell中的错误.他们的意思是同样的事情.您可以阅读Bennett Todd’s explanation中的详细信息(在gbacon的答案中复制).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读