解析器文件--Interpreter File

来源:互联网 发布:mac显示硬盘隐藏文件 编辑:程序博客网 时间:2024/06/05 19:35

刚看了apue的关于解析器文件的部分,感受颇多,记录一下吧。

解析器文件是一种文本文件,文件的第一行的形式:#!  pathname  [optional-argument]

其中pathname指的时解析器名称,optional-argument是传递给解析器的参数。其实我们大家最熟悉的解析器文件就是shell脚本文件,shell脚本文件第一行都是#! /bin/sh。

解析器文件是一种文本文件,而解析器是可执行的二进制文件。解析器是由解析器文件的第一行指定的。

例如一个displayArgTab程序,用于显示执行该程序时的参数表,代码如下:

//name:displayArgTabint main(int argc, char *argv[]){        int i;        for(i = 0; i<argc ;i++)                printf("argv[%d]: %s\n", i,  argv[i]);               return 0;}
以displayArgTab为解析器,写一个解析器文件,如下:

//解析器文件名为testInterpreter#! /tmp/displayArgTab  arg
生成的解析器文件testInterpreter也放在/tmp/下。下面通过execl来调用解析器文件:

 if(execl("/tmp/testInterpreter", "testInterpreter", "myarg1", "myarg2", (char*)NULL) < 0) {      printf("execl  error...\n");      return 0; } 
执行结果为:

argv[0]: /tmp/displayArgTab
argv[1]: arg
argv[2]: /tmp/testInterpreter
argv[3]: myarg1
argv[4]: myarg2

由此可以得知内核在执行解析器文件时,向解析器传递的参数依次是:

  • 解析器的pathname-路径名;
  • 解析器的可选参数(如果没有则不会传递);
  • exec的解析器文件的pathname-路径名;
  • exec的第二个参数;
  • exec的第三个参数,......;

有些程序是用脚本语言写的,解释器文件可将这一事实隐藏起来,例如shell脚本,awk脚本。例如下面是一段awk脚本,由awk程序进行解析。

#! /bin/awk -fBEGIN {        for(i = 0; i < ARGC; i++)                printf "ARGV[%d] = %s\n", i, ARGV[i]        exit}
上面#!后接的时该解析器文件的解析器awk程序,和解析器的参数-f;下面的脚本程序是按awk语法所写的脚本,功能是显示传递给awk脚本的参数。

测试结果如下:

//脚本文件名为testAwk$ ./testAwk arg1 arg2 arg3ARGV[0] = awkARGV[1] = arg1ARGV[2] = arg2ARGV[3] = arg3
在运行文件testAwk时,要赋予x权限。上述执行解析器文件testAwk的过程实际是这样的:

  • 首先shell读取这个命令时,首先会认为它是一个机器可执行的文件,即二进制的机器语言,shell会试图execl此文件名,但该文件时一个脚本文件,即文本文件,对于机器来说是不可执行的,所以会返回错误。
  • 返回错误后,shell就认为该文件是一个解析器文件(脚本文件)。然后调用该解析器文件的解析器解析脚本文件的内容。

当然上述执行过程可以直接调用解析器文件的解析器来直接运行,如下:

$ awk -f testAwk arg1 arg2 arg3ARGV[0] = awkARGV[1] = arg1ARGV[2] = arg2ARGV[3] = arg3
这样执行的效率肯定比直接执行脚本的效率要高,因为省略了上述第一个过程。

欢迎大家批评指正!

Sep 29, 2012 PM 20:28 @lab