`

解释器文件

阅读更多
    解释器文件是一种文本文件,其起始行的形式是:
        #! pathname [optional-argument]
    其中感叹号和 pathname 之间的空格是可选的。pathname 通常是绝对路径名,对它不进行什么特殊处理(不使用 PATH 进行路径搜索),它后面的参数(如果有)无论多少都会被作为一个参数来对待。对这种文件的识别是由内核作为 exec 系统调用处理的一部分来完成的。内核使调用 exec 函数的进程实际执行的并不是该解释器文件,而是 pathname 所指定的解释器。
    很多系统对解释器文件的第一行都有长度限制,比如 Linux 3.2.0 中该限制为 128 字节。
    下面这个程序 interFileDemo.out 调用 exec 执行一个解释器文件,演示了当被执行的文件是个解释器文件时,内核如何处理 exec 函数的参数以及该解释器文件第一行的可选参数。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void){
	pid_t	pid;
	if((pid=fork()) < 0){
		printf("fork error\n");
		exit(2);
	}
	if(pid == 0){
		if(execl("./testInterp", "testInterp", "arg1", "arg2", (char *)0) < 0){
			printf("execl error\n");
			exit(2);
		}
	}
	if(waitpid(pid, NULL, 0) < 0){
		printf("waitpid error\n");
		exit(2);
	}
	exit(0);
}

    这里的解释器文件“./testInterp”只有一行内容:
        /home/me/bin/echoarg foo bar
    而它所指定的解释器 echoarg 的源代码如下。
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
	int i;
	for(i=0; i<argc; i++)
		printf("argv[%d]: %s\n", i, argv[i]);
	exit(0);
}

    运行结果如下(这 3 个文件都需要有执行权限):
$ ./interFileDemo.out 
argv[0]: /home/me/bin/echoarg
argv[1]: foo bar             # 这里把它们都合并成一个参数了
argv[2]: ./testInterp        # 取的是 exec 调用中的 pathname,而非 arg0
argv[3]: arg1
argv[4]: arg2

    在解释器 pathname 后可跟随可选参数,比如 awk(1) 程序支持“awk -f myfile”,它告诉 awk 从文件 myfile 中读 awk 程序,在解释器文件中可以写成:
        #!/bin/awk -f
    比如下面这个关于 awk 的解释器文件程序 awkexample。
#!/usr/bin/awk -f
# Note: on Solaris, use nawk instead
BEGIN{
	for(i=0; i<ARGC; i++)
		printf "ARGV[%d] = %s\n", i, ARGV[i]
	exit
}

    执行该程序得到如下结果:
$ ./awkexample file filename2 f3
ARGV[0] = awk
ARGV[1] = file
ARGV[2] = filename2
ARGV[3] = f3

    执行 /bin/awk 时,其命令行参数是:
        /bin/awk -f ./awkexample file filename2 f3
    可用下列命令验证上述命令行参数。
$ /bin/su
密码:
# mv /usr/bin/awk /usr/bin/awk.save
# cp ./echoarg /usr/bin/awk
# suspend                                # 用作业控制挂起超级用户 shell
[1]+  Stopped                 /bin/su
$
$ ./awkexample file filename2 f3         # 这时的 /usr/bin/awk 实际上是 echoarg
argv[0]: /usr/bin/awk
argv[1]: -f
argv[2]: ./awkexample
argv[3]: file
argv[4]: filename2
argv[5]: f3
$
$ fg
/bin/su
$ mv -f /usr/bin/awk.save /usr/bin/awk
# exit
$

    注意,如果不能向解释器传递可选参数,那么该解释器文件只有对 shell 才是有用的。
    解释器文件可使用户得到效率方面的好处,代价是内核的额外开销(因为是内核识别接解释器文件)。由于下述理由,解释器文件是有用的。
    1、隐藏程序的编写语言。比如要执行上面的 awkexample 程序,只需要使用命令:
         ./awkexample optional-arguments
       而没必要知道该程序是一个 awk 脚本,否则就需要以下列方式执行程序:
         awk -f awkexample optional-arguments
    2、解释器脚本在效率方面也提供了好处。假设将上面的 awkexample 代码放在一个普通 shell 脚本中:
awk 'BEGIN{
	for(i=0; i<ARGC; i++)
		printf "ARGV[%d] = %s\n", i, ARGV[i]
	exit
}' $*

       这种方法将会做更多的工作。首先,shell 读此命令,然后试图 execlp 此文件名。因为 shell 脚本是一个可执行文件,但却不是机器可执行的,于是返回一个错误,execlp 就认为该文件是一个 shell 脚本(它实际上就是),然后执行 /bin/sh,并以该 shell 脚本的路径名作为其参数。尽管 shell 能正确地执行这个 shell 脚本,但是为了运行 awk 程序,它会调用 fork、exec 和 wait,所以用一个 shell 脚本代替解释器脚本需要更多的开销。
    3、解释器脚本使我们可以使用 /bin/sh 以外的其他 shell 来编写 shell 脚本。当 execlp 找到一个非机器可执行的可执行文件时,它总是调用 /bin/sh 来解释执行该文件。而用解释器脚本则可简单地使用“#!/bin/csh”之类的来代替。
分享到:
评论

相关推荐

    文件后缀名解释器 文件后缀名解释器

    文件后缀名解释器是一个工具,它的主要功能是解析和提供关于各种文件后缀名的信息。这个工具可以帮助用户了解不熟悉的文件类型,提供有关如何打开、编辑或转换文件的指导。通过输入文件后缀名,解释器可以返回该后缀...

    lua-5.1.4 的 lib 文件 及 解释器 编译器

    在lua-5.1.4中,主要的解释器文件名为`lua`或`luac`。`lua`是交互式解释器,可以直接运行Lua脚本或者在命令行中输入Lua代码;`luac`是编译器,用于将Lua源码编译成字节码,以提高运行效率和保护代码,生成的字节码...

    文件后缀名解释器.EXE

    文件后缀名解释文件后缀名解释器.EXE器.EXE 文件后缀名解释器.EXE

    Ansy.rar_C语言解释器_解释 语言_解释器_解释器模式_语言解释器

    《C语言解释器的实现与解释器模式解析》 在编程世界中,编译器和解释器是两种关键的工具,它们将高级编程语言转换为机器可以理解的指令。本篇我们将聚焦于“C语言解释器”的实现,以及在设计过程中所采用的“解释器...

    FLV(Flash Video) 文件解释器

    从网友那得到的一个简单实用的家用FLV文件解释器,对想要理解FLV文件格式的同学来说,很有帮助

    文件后缀名解释器

    本“文件后缀名解释器”致力于帮助用户理解和处理各种未知或不熟悉的文件后缀。 文件后缀名解释器是一个实用工具,它的主要功能是解析和提供关于各种文件后缀名的信息。当你遇到不熟悉的文件后缀时,你可以通过这个...

    VBA程序解释器.rar

    标题中的“VBA程序解释器.rar”指的是包含VBA解释器的压缩文件,它可能是一个包含了用于执行VBA代码的组件或者工具。 在描述中提到的流程是安装并信任VBA组件的步骤,这是为了确保安全性和避免未知的宏病毒。在运行...

    文件后缀解释器 v1.0

    《文件后缀解释器 v1.0:理解与探索》 在数字时代,我们每天都会接触到各种类型的文件,而文件的后缀名是识别文件类型的重要标志。"文件后缀解释器 v1.0" 是一款专为普通用户设计的应用软件,旨在帮助用户理解和...

    delphi编写的小型解释器

    在IT领域,编程语言的解释器是至关重要的工具,它能读取并执行特定语言编写的脚本。本文将深入探讨使用Delphi编程环境构建小型解释器的过程,以及相关的关键技术点。 首先,我们要理解“解释器模式”。这是一种设计...

    cmm解释器大作业

    在本项目中,"cmm解释器大作业"是一个典型的计算机科学课程作业,涉及到了编译原理中的核心概念。这个作业旨在让学生通过实践理解并掌握词法分析、语法分析以及语义分析等编译器设计的关键步骤。武汉大学的这个实践...

    文件后缀名解释器(免费的)

    文件后缀名解释器,可以帮住新手查看一些不常见的文件类型,以防误删一些系统文件

    Lua5.3 源码 编译器 解释器 库文件

    官网下载的源码 然后自己生成了编译器 解释器和库文件 只需要把你的lua文件放在与lua exe同一目录然后运行lua exe 输入dofile &quot;lua文件名&quot; 回车就可以运行lua文件啦 方便新手用

    delphi代码解释器

    Delphi代码解释器是一种特殊的软件工具,主要用于解析和执行Delphi编写的源代码,而无需先将代码编译成机器可执行的二进制文件。它通常由两部分组成:解释器引擎和编译器。解释器引擎负责读取、理解和执行Delphi代码...

    VBScript解释器源码

    而“一个小巧的BASIC解释器的源代码”可能是另一个可供学习的资源,尽管它不是VBScript,但BASIC语言和VBScript有很多共同之处,理解BASIC解释器也能帮助理解VBScript的工作方式。 总的来说,通过深入研究和实践...

    完整cmm解释器

    与编译器不同,解释器不创建独立的可执行文件,而是直接在内存中运行代码。 6. **GUI(图形用户界面)**:使用SWT(Standard Widget Toolkit)框架,该解释器提供了用户友好的图形界面,使得用户可以直接在界面上...

    开源basic解释器

    源代码文件通常包含C、C++、Python等编程语言编写的核心解释器模块,以及可能的测试用例、示例代码和文档。通过阅读和分析源代码,开发者可以深入了解解释器的内部工作机制,如语法解析、语义分析、符号表管理、内存...

    BASIC解释器的源代码

    总的来说,这个压缩包中的文件提供了一个深入学习编译器和解释器工作原理的实例,无论你是初学者还是经验丰富的开发者,都可以从中受益。通过实际操作和修改源代码,你将有机会亲手创建一个能够理解和执行代码的程序...

    魔王语言解释器

    "魔王语言解释器Dlg.cpp"和"魔王语言解释器Dlg.h"可能涉及到图形用户界面(GUI)的设计,这些文件可能包含了对话框类的实现和声明,用户可以通过这个对话框输入"魔王语言"并查看翻译结果。"shuru.cpp"可能是处理用户...

    C语言子集解释器

    解释器是计算机程序的一种,它可以读取另一种编程语言(在这里是C语言的子集)的源代码,并逐行执行这些指令,而无需先将其转换为可执行文件。这与编译器不同,编译器会将源代码一次性转换为目标平台的机器语言,...

Global site tag (gtag.js) - Google Analytics