解释Perl“前导”的瑕疵

前端之家收集整理的这篇文章主要介绍了解释Perl“前导”的瑕疵前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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的答案中复制).

原文链接:https://www.f2er.com/Perl/172541.html

猜你在找的Perl相关文章