Chinaunix首页 | 论坛 | 博客
  • 博客访问: 979821
  • 博文数量: 184
  • 博客积分: 10030
  • 博客等级: 上将
  • 技术积分: 1532
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-27 18:32
文章分类

全部博文(184)

文章存档

2009年(1)

2008年(63)

2007年(39)

2006年(79)

2005年(2)

我的朋友

分类:

2007-01-22 10:50:23

话题:
 
请问${1+"$@"}是什么意思啊?   
#!/usr/bin/perl
    eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
            if $running_under_some_shell;
 
 
以下是flw版主的回复:
 
 
这几行程序包含了太多的技巧。
的确需要很深的功力才能看得懂。

首先解释一下,# 打头的行在 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+"$@"} 的区别。

阅读(1549) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~