man有如下8个模块.
1 shell中用户可用的命令
2 使用函数库中程序可用的系统调用
3 程序中可用的库函数
4 /dev目录中可用的设备
5 多种杂项系统文件(ex:/etc/)
6 如果有的话,游戏程序
7 杂项信息
8 管理员可用的命令
1)man命令是如何搜索命令对映的帮助文件的?
2)帮助文件的文件格式和结构是怎么的?
3)如何创建一个man的帮助文件?
4)whatis和apropos的运行流程是如何的呢?
第一个问题:
man命令搜索流程
第一步:$PATH变量指定的路径
第二步:/etc/man.config文件中MANPATH中指定的路径
程序执行流程:
1)程序首先会试图加载/etc/man.config文件,将man.config的内容读入内存,
2)将man.config文件中"MANSECT 1:8:2:3:4:5:6:7:9:tcl:n:l:p:o"读入到内存
MANSECT是man查找的顺序,例如上面的这个顺序就是如果查到shell命令和系统调用,将优先打印shell命令
3)通过man.config和$PATH,确定出要搜索的目录
4)通过fstat系统调用,确认存在的目录.
5)确定查找到的命令/函数所对映的模块,例如sync命令的顺序是1:8:2,可以通过man -a sync来确认
6)根据对映的模块找到对映man帮助文件,这里通过open打开第4步中存在的目录,依次查找对映的帮助文件(顺序见man命令的搜索流程)
说明:
1)在第一步加载man.config的过程中,如何没有找到/etc/man.config文件.程序将继续运行,并只根据$PATH来搜索帮助文件
2)在man.config中可以加入自定义的搜寻目录,man程序会判断搜索目录中是否存在man目录和MAN目录.
例如:定义了/tmp目录,man程序会搜索/tmp/man和/tmp/MAN还有/tmp三个目录.
3)man.config中定义了压缩与解压缩的方式,但如果man.config不可读,man程序依然可以解压以gzip压缩的帮助文件.
如果以其它压缩格式,man程序将无法解压.例如用bunzip2压缩的帮助文件.
4)用manpath命令可以看到man.config中MANPATH指定的路径.但这不包括变量PATH中指定的路径.
第二个问题:
man程序读取的帮助文件格式分为两大类.
第一类为troff程序编写的源程序.
第二类为通过压缩工具压缩过的源程序.
man程序可以直接读取的格式,是第一大类,和第二大类中用gzip压缩的帮助文件.
其它格式要用man.config中定义的解压缩工具处理,才可以阅览.
例如:
.gz /bin/gunzip -c
.bz2 /usr/bin/bzip2 -c -d
.z
.Z /bin/zcat
.F
.Y
这里说明,.gz格式的用gunzip -c来直接读取,而.bz2用bzip2 -c -d来读取,.Z用/bin/zcat来读取
帮助文件默认的路径为/usr/share/man和/usr/local/man/
其中/usr/share/man存放了绝大多数的帮助文件,而且都是压缩格式的帮助文件.
/usr/local/man存放的都是以文本格式的帮助文件.
/usr/share/man中的子目录是对映的模块.例如man1目录中存放的帮助文件是“shell中用户可用的命令”
而文件名,是命令名/函数名加上模块的序号,如果是压缩格式,再加入压缩的扩展名即可.
例如:
host.1.gz即是程序名(host).模块的序号(1).扩展名(gz)
第三个问题:
例如,自己写一个测试程序hello.c
如下:
#include <stdio.h>
int main()
{
printf ("Hello world,This is a test!\n");
return 0;};
编译:
gcc -o hello hello.c
在/usr/share/man/创建一个 man文件.
文件名要讲规范.本例为hello.1
文件内容如下 :
.\" $Id: hello.1,v 1.11.2.2 2009/06/7 04:44:38 marka Exp $
.\"
.TH "Hello" "1" "Jun 7, 2009" "hacker" ""
.SH NAME
Hello \- This is a test.Display hello strings.
.SH SYNOPSIS
.sp
\fBhello\fR
.SH "DESCRIPTION"
.PP
\fBhello\fR
is a simple test for show man program.
\fBhello\fR
prints a short test message.
.PP
print follow as:
Hello world.This is a test.
.SH "FILES"
.PP
\fBhello\fR
.SH "SEE ALSO"
.PP
\fBprintf\fR(1),
\fBstdio.h\fR(8).
这样即就可以为hello程序建立man文件了.当然你没有hello的可执行程序也是可以运行man hello的.
现在可以用man -aw hello来查看hello命令的man文件了.
第四个问题:
whatis的运行流程如下:
1)搜索/var/cache/man/whatis文件.
/var/cache/man/whatis是文本文件.
2)如果/var/cache/man/whatis不存在. 到man.config中MANPATH指定的路径到搜索whatis文件
说明:
1)与man命令搜索不同之处在于,man命令会首先搜索PATH变量指定的路径.
2)如果找到两个whatis文件,将显示两遍相同的命令.
例如:
whatis ls
ls (1) - list directory contents
ls (1) - list directory contents
3)新建一个man文件,例如上面的hello.1,这时用whatis是找不出对映信息的,因为还没有同步到/var/cache/man/whatis文件中.
如果要同步,可以直接用makewhatis -u -w更新whatis文件.
4)在/etc/cron.daily目录下有个makewhatis.cron脚本,它的任务就是每天更新whatis文件的.
apropos的运行流程与whatis一样.但apropos是借助whatis文件进行全文搜索.