设为首页 收藏本站
查看: 1141|回复: 0

[经验分享] eval 'exec perl -w -S $0 ${1+"$@"}'的作用

[复制链接]

尚未签到

发表于 2018-8-31 13:46:51 | 显示全部楼层 |阅读模式
这几行程序包含了太多的技巧。  的确需要很深的功力才能看得懂。
  首先解释一下,# 打头的行在 shell 中表示该行是注释行,但是如果该脚本具有可执行权限,
  而直接执行(如 C 的 exec* 系列系统调用,或者 shell 下直接敲脚本名称)的时候,该行
  起到指示解释器的作用。在本例中,指定解释器是 /usr/bin/perl(假设用户的系统上已经
  安装了 Perl 并且安装位置就在 /usr/bin/perl 否则该脚本无论如何都是无法执行的)
  当一个用户拿到脚本时,根据个人习惯和知识水平的不同,可能会有以下三种执行脚本的方法:
  执行方式 1,./foo
  使用 chmod +x foo 赋予了脚本可执行权限之后,就可以用这种方法来执行。
  前面说了,这种方式执行的时候,OS 会去按照脚本第一行 #! 的指示去寻找 interpreter
  的位置,在这里也就是 /usr/bin/perl,所以一旦找到 /usr/bin/perl,后面的两行
  eval 'exec /usr/bin/perl ......' if $rrunning_under_some_shell; 就会被当作 Perl
  代码来执行。因为 $running_under_some_shell 这个变量没有被定义过,因此它的值为
  undef,也就是说 if 修饰符会失败,从而导致 eval 这句不会被执行。因此在这种情况下,
  如果系统中已经安装了 Perl 并且 Perl 的位置就是在 /usr/bin/perl 的话,这两行就相当于什么都没有
  注意在 Perl 中换行符作为空白符是可以任意添加的,所以这两行合起来实际上是一个完
  整的语句。但是这里面有个技巧,它故意写成了两行,原因在下面解释。
  执行方式 2,perl foo
  当用户已经知道这个脚本是一个 Perl 脚本的时候,就可以用这种方式执行。这种方式和
  第一种方式基本相同,唯一不同的地方就是 #!/usr/bin/perl 会被当成普通的 Perl 注释。
  执行方式 3,sh foo
  这种方式下,用户误以为 foo 是一个 shell 脚本,因此调用了 shell 来执行这个脚本。
  此时,第一行 #! 会被 shell 当作普通的注释而忽略。在这种情况下,eval 会被当作一个
  shell 命令来解释,它的参数 'exec /usr/bin/perl ....' 则是一个合法的 shell 命令,
  其作用就是重新调用 /usr/bin/perl 来解释此脚本,shell 参数 $0 在这种情况下其实就是
  脚本自身的名称。而 "$@" 也就等于 "$1" "$2" "$3" ... 也就是脚本的参数(注)。也就是说:
  如果该脚本被错误地当作 shell 脚本来执行,那也没问题,因为它也是一个
  合法的 Perl 脚本 注意这里故意把 if 修饰符另起一行来写,是为了保证 eval
  那行是一个正确的 shell 语句。因为 eval 那行一旦执行成功,exec 会覆盖当前进程,
  因此 if 这一行根本就没有执行的机会,也就不会出错。
  总结:
  这么写的作用,是为了让这个脚本既能用 perl 来解释,也能用 shell 来解释。如果当
  用 perl 来解释,固然正确,但是即使用 shell 来解释,也不仅不会出错,还会得到同
  样的结果。
  注:这个地方通常写作 "$@" 但是在你这个例子里不知为何写成 ${1+"$@"},也许另有深意,我
  查了一下,在我的系统(Debian 4.0)中,两种写法都有。如果你有兴趣,可以去 shell
  版再请教一下 "$@" 和 ${1+"$@"} 的区别。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-559439-1-1.html 上篇帖子: perl生成6位随机数字 下篇帖子: windows安装perl模块
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表