Fork me on GitHub

解释器文件

解释器文件

所有现今的UNIX系统都支持解释器文件(interpreter file)。这种文件是文本文件,其起始行的形式是:

1
#! pathname[optional-argument]

在感叹号和pathname之间的空格是可选的。最常见的解释器文件以下列行开始:

1
#! /bin/sh

pathname通常是绝对路径名,对它不进行什么特殊的处理(不使用PATH进行路径搜索)。对这种文件的识别是由内核作为exec系统调用处理的一部分来完成的。内核使调用exec函数的进程实际执行的并不是该解释器文件,而是在该解释器文件第一行中pathname所指定的文件。一定要将解释器文件(文本文件,它以#!开头)和解释器(由该解释器文件第一行中的pathname指定)区分开来。

示例

execl执行的文件是一个解释器文件时,内核如何处理execl参数及该解释器文件第一行的可选参数。

execinterp.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "head.h"
int main(void){
pid_t pid;
if((pid = fork()) < 0){
printf("fork error\n");
}else if(pid == 0){ //child
if( execl("/home/vrlive/linuxProgram/apueProgram/eight/testinterp","testinterp","myarg1","MY ARG2",(char*)0) < 0){
printf("execl error\n");
}
}
if(waitpid(pid,NULL,0) < 0){ //parent
printf("waitpid error\n");
}
exit(0);
}

其中testinterp为解释器文件,之前运行老出错,是因为testinterp文件没有可执行权限。

1
2
3
4
[vrlive@iZ23chs2r19Z eight]$ ll | grep testinterp
-rwxrwxr-x 1 vrlive vrlive 61 May 14 16:51 testinterp
[vrlive@iZ23chs2r19Z eight]$ cat testinterp
#! /home/vrlive/linuxProgram/apueProgram/eight/echoarg.o foo

echoarg.o是echoarg.c的可执行文件,回显每一个命令行参数。

echoarg.c

1
2
3
4
5
6
7
8
9
#include "head.h"
int main(int argc,char *argv[]){
int i = 0;
for(i = 0;i<argc;++i){
printf("argv[%d]: %s\n",i,argv[i]);
}
exit(0);
}

输出结果:

1
2
3
4
5
6
[vrlive@iZ23chs2r19Z eight]$ ./execinterp.o
argv[0]: /home/vrlive/linuxProgram/apueProgram/eight/echoarg.o
argv[1]: foo
argv[2]: /home/vrlive/linuxProgram/apueProgram/eight/testinterp
argv[3]: myarg1
argv[4]: MY ARG2

当内核exec解释器时(/home/vrlive/linuxProgram/apueProgram/eight/echoarg.o)时,argv[0]是该解释器的pathname,argv[1]是解释器文件中的可选参数,其余参数是pathname(excel函数pathname参数值/home/vrlive/linuxProgram/apueProgram/eight/testinterp)以及execl的第2个和第3个参数(myarg1、MY ARG2)。调用execl时的argv[1]和argv[2]已右移了两个位置。

注意,内核取execl调用中的pathname而非第一个参数(testinterp),因为一般而言,pathname包含了比第一个参数更多的信息。

后续待补充

-------------本文结束感谢您的阅读-------------

本文地址:http://www.wangxinri.cn/2018/05/14/解释器文件/
转载请注明出处,谢谢!

梦想夹带眼泪,咸咸的汗水!