eval '(exit $?0)' && eval 'exec perl -wS $0 ${1+"$@"}' & eval 'exec /usr/bin/perl -wS $0 $argv:q' if $running_under_some_shell;
呃真的吗?有人可以详细解释一下这个工作吗?
解决方法
在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命令应该在subshell中进行求值.
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的答案中复制).