以binx结尾的线刷文件,用SML.exe可以解压(如CoolpadSML_CustomService_2.000.0015.20130304.01包里的文件),解压后得到很多后缀为.img的文件,每个文件对应Android的一个文件夹,如system.img、userdata.img等。这些文件在Widowns下用7zip无法打开,说明不是能识别的压缩文件。通过linux下的file -sL userdata.img看类型,弊纯得到是data的提埋腊示,system.img也同理通过simg2img可以将userdata.img解压,simg2img userdata.img userdata.raw对userdata.raw执行file -sL命令后,可以得到ext4格式的文件用7zip可以打弯卜滑开userdata.raw,也可以在linux用mount命令将raw文件挂载到某个目录。
recovery.img的压缩和别的不一样,它是gzip压缩的cpio文件,解压过程请参考:
《recovery: ASCII cpio archive (SVR4 with no CRC)——cpio格式的recovery解压缩和重新打包的方法》
网址是:http://blog.csdn.net/whu_zhangmin/article/details/25184495
注:
通过《Android中system.img的两种格式及其相互转换方法》可以知道simg2img将sparse镜像文件转换成raw镜像文件,
“system/core/libsparse/simg2img.c // 将sparse image转换为raw image;
system/core/libsparse/img2simg.c // 将raw image转换为sparse image;”
详细介绍在http://blog.csdn.net/howellzhu/article/details/43165507
关于各img作用的介绍请参考《Android ramdisk.img system.img userdata.img介绍与使用》,
链接是http://blog.csdn.net/superfang119/article/details/8557223
⑵ GDB如何从Coremp文件恢复动态库信息
查看 error log:
可以看到前面这串文字是一个函数签名的编码,用 c++filt 还原编码以后,可以看到完整的函数签名。
红框内的这串信息的意思就是崩溃位置是 一个函数起始位置 + 偏移量。
我们大概可以猜到,这个 MySQL 的缺陷是在为 binlog 产生新的文件名时发生的。
小贴士:
函数起始位置 + 偏移量 是一种内存位置的表示方法,但该位置不一定是这个函数内的代码。
以本例来说,0xee36f1 这个位置,程序找到了就近的函数 generate_new_name 的起始位置,计算出有 0x71 这么多偏移,就表示成了 generate_new_name+0x71 这种形式。
但 0xee36f1 这个位置的代码,大概率是,但,不一定是 generate_new_name 这个函数内部的一段代码。
⑶ gdb添加移除工作目录
目录、终端类型以及程序运行的搜索目录这些信息。通常你用shell设置的环境变量会被所有你运行的其他程序所继承。调试时,不需要反复启动GDB就可以使用一个修改的环境变量试着运行程序,是很有用的。
path directory
在传递给程序的PATH环境变量(可执行程序的搜索路径)前,添加directory。GDB所使用的PATH值不会被更改。可以指定若干的目录名,使用空格或系统相关的分隔符(UNIX上是“:”,MS-DOS和MS-Windows上是“;”)分隔它们。如果directory已经在PATH中了,就把它移到前面,以使它可以被立即搜索到。 可以使用字符串“$cwd”,在GDB搜索路径时,引用当前工作目录。如果使用“.”代替的话,它引用的是由执行path命令指定的目录。在添加directory到搜索路径之前,GDB在directory参数中替换“.”(使用当前路径)。
show path
显示可执行文件的搜索路径列表(PATH环境变量)。
show environment [varname]
打印程序启动时惯于它的环境变量varname的值。要是没有给出varname,就打印所有惯于程序的环境变量的名和它的值。可以用env简写environment。
set environment varname [=value]
给环境变量varname赋值为value。变量值的更改仅针对于程序,不会影响GDB本身。value可以是任何字符串——环境变量值只能是字符串,对它的任何解释都由程序本身提供。value参数是可选的。如果去除的话,变量会被赋予一个null值。 例如这个命令:
set env USER = foo
告诉GDB,在随后的run时,它的用户是一个名叫“foo”的(“=”前后使用的空格是为了清晰,实际上是不需要的)。
unset environment varname
从传递给程序的环境中移除变量varname。这与“set environment varname=”不同,它是从环境中移出变量,而不是给它赋一个空值。
警告:在UNIX系统中,如果有SHELL环境变量的话,GDB使用的是它指定的shell(没有的话使用/bin/sh)。如果你的SHELL环境变量指定了一个运行初始化文件(如C-Shell的“.cshrc”或者是BASH的“.bashrc”)的shell,掘大你设置在那个文件中的任何变量,都会对你的程序有所影响。你可能希望把这些环境变量的设置移到仅在你注册时运行的文件中去,这样的文件有“.login”或“.profile”。
4.5 程序的工作目录
每次使用run启动的程序,都GDB的当前工作目录继承为它的工作目录。GDB的工作目录最初是继承自它的父进程(通常是shell),不过,你可以在GDB中早散瞎使用cd命令指定一个新的工作目录。
GDB的工作目录也担当着GDB操作的指定文件命令的默认目录。参见指定文件的命令一节。
cd directory
设置GDB的工作目录为directory。
pwd
打印GDB的当前工作目录。
找到正被调试的进程的当前工作目录,通常是做不到的(因为一个程序可以在它运行的时候改变它的目录)。如果你工作在GDB可以被配置为带有“/proc”支持的系统上的话,你可以利用info proc命令(见18.1.3 SVR4进程信息一节)找到debuggee的当前工作目录。
4.6 程序的输入输出
默认情况下,GDB下运行的程序作输入输出的终端,与GDB所使用的是相同的。GDB把终端转换为它自己的终端方式与你交互,不过,它记录你的应用程序所使用的终端方式,当你继续运行你的程序时,它再切换回来。
info terminal
显示由GDB记陆空录下来的程序所使用的终端模式的信息。
可以使用run命令,利用shell的重定向,重定向程序的输入和/或输出。
启动程序,驱使他的输出到文件“outfile”。
另外一种指定程序在何处做输入输出的方式是使用tty命令。这个命令接受一个作为参数的文件名,并使这个文件成为之后run命令的默认重定向目标。它也为子进程、之后的run命令重置控制终端。例如:
指示后续用run命令启动的进程默认在终端“/dev/ttyb”上作输入输出,并且拿这个作为它们的控制终端。
在run中明确的重定向,优先于tty对输入/输出设备的影响,但是并不对控制终端有影响。
当使用tty命令或在run命令中重定向输入时,只有程序的输入会受到影响。GDB的输入依然来自你的终端。tty是set inferior-tty的别名。
可以使用show inferior-tty命令告诉GDB,显示将来程序运行会被使用的终端的名字。
set inferior-tty /dev/ttyb
设置正被调试的程序的tty为/dev/ttyb。 tty /dev/ttyb run > outfile
show inferior-tty
显示正被调试的程序的当前tty。
4.7 调试某个已运行的进程
attached process-id
这个命令附着到一个正在GDB以外运行的进程。(info文件显示活动目标)这个命令带有一个process-id参数。要找到某个UNIX进程的process-id,通常的方式是使用ps工具,或者使用“jobs –l”shell命令。
attached命令执行之后,第二次按RET的话,是不会被重复的。
为了使用attached,程序必须运行在一个支持进程的环境下。例如:对于在缺乏操作的bare-board目标上的程序,attached是不会工作的。也必须得有发送信号的权限。
当使用attached的时候,调试器首先定位当前目录中正运行在进程中的程序,然后(如果没有发现这个程序)查看元文件搜索路径(参见指定源文件目录一节)。你也可以利用file命令装载程序。参见指定文件的命令一节。
准备好要调试的指定进程后,所做的第一件事就是停止进程。检查与修改被附着的进程,可以使用平常使用run启动进程时能够用到的所有命令。可以插入断点;可以单步调试并继续;可以修改存储器。如果你愿意让进程继续运行的话,你可以在将GDB附着到进程之后使用continue命令。
detach
当对被附着的进程的调试完成时,可以使用detach命令,把它从GDB的控制下释放出来。分离进程而继续执行。detach命令之后,那个进程与GDB再一次变得完全独立,并且准备附着另外一个进程,或者使用run命令启动一个。detach命令执行之后,再按RET的话,是不会被重复的。
当已附着到一个进程时,退出GDB或使用run命令,会杀掉那个进程
⑷ 查找/etc/passwd目录中以r开始的字符串,命令怎么写
在Linux /etc/passwd文件中每个用户都有一个对应的记录行,它记录了这个用户的一些基本属性。
系统管理员经常会接触到这个文件的修改以完成对用户的管理工作。这个文件对所有用户都是可读的。如下;
1.username 用悔并户名它唯一地标识了一个用户帐号,用户在登录时使用的就是它。由大小写字母和/或数字组成。登录名中不能有冒号(因为冒号在这里是分隔符。为了兼容起见,登录名中最好不要包含点字符(.),并且不使用连字符(-)和加号(+)打头。
2.password 该帐号的口令passwd文件族晌中存放的密码是经过加密处理的。Linux的加密算法很严密,其中的口令兆前锋几乎是不可能被破解的。现在许多Linux系统(如SVR4)都使用了shadow技术,把真正的加密后的用户口令字存放到/etc/shadow文件中,而在/etc/passwd文件的口令字段中只存放一个特殊的字符,例如“x”或者“*”。
⑸ 系统linux 跪求【find .|cpio -o -H newc|gzip>~/myinitramfs.gz】 的详细解释。。一定采纳
|find .|cpio -o -H newc|gzip>~/myinitramfs.gz
1. find . 查找显示当前目录下的所有文件、文件夹
2. | 管道,将 | 左边命令的结果专(也就属是find . 得到的所有文件、文件夹路径名称)传给右边(也就cpio命令)
3. cpio -o -H newc cpio是将文件系统打包或解包, -o 是打包 ,-H 指定格式 为newc
newc The new (SVR4) portable format, which supports file systems having more than 65536 i-nodes. (4294967295 bytes)
4 | 将cpio打好的包传给gzip压缩
5 gzip 压缩命令的一种,gnuzip。类似zip,rar。
6 >~/myinitramfs.gz 将压缩后的数据 存为 文件myinitramfs.gz
⑹ linux内核模块如何开始和结束
GRLB 加载了内核之后,内核首先会再进行二次系统的自检,而不一定使用 BIOS 检测的硬件信息。这时内核终于开始替代 BIOS 接管Linux的启动过程了。
内核完成再次系统自检之后,开始采用动态的方式加载每个硬件的模块,这个动态模块大家可以想象成硬件的驱动(默认 Linux 硬件的驱动是不需要手工安装的,如果是重要的功能,则会直接编译到内核当中;如果是非重要的功能,比如硬件驱动会编译为模块,则在需要时由内核调用。不过,如果没有被内核硬件,要想驱动,就需要手工安装个硬件的硬块了。具体的安装方法会在后续章节中介绍)。
那么,Linux 的内核到底放在了哪里呢?当然是 /boot 的启动目录中了,我们来看看这个目录下的内容吧。
[root@localhost ~]#ls /boot/
config-2.6.32-279.el6.i686
#内核的配置文件,内核编译时选择的功能与模块
efi
#可扩展固件接口,为英特尔为全新PC固件的体系结构、接口和服务提出的建议标准
grub
#启动引导程GTUB的数据目录
initramfe-2.6.32-279.el6.i686.img
#虚拟文件系统(CentOS 6.x 中用initramfs替代了initrd,但功能是一样的)
lost+found
故boot分区的备份目录
symvers-2_6.32-279.el6.i686.gz
#模块符号信息
System.map-2.6.32-279.el6.i686
#内核功能和内存地址的对应列表
vmlinuz-2.6.32-279.el6.i686
#用于启动的Linux内核。这个文件是一个压缩的内核镜像
我们已经知道,Linux 会把不重要的功能编译成内核模块,在需要时再调用,从而保证了内核不会过大。在多数 Linux 中,都会把硬件的驱动程序编译为模块, 这些模块保存在 /lib/moles/ 目录中。常见的 USB、SATA 和 SCSI 等硬盘设备的驱动,还有一些特殊的文件系统(如 LVM、RAID 等)的驱动,都是以模块的方式来保存的。
如果 Linux 安装在 IDE 硬盘之上,并且采用的是默认的 ext3/4 文件系统,那么内核启动后加载根分区和模块的加载都没有什么问题,系统会顺利启动。但是如果 Linux 安装在 SCSI 硬盘之上,或者采用的是 LVM 文件系统,那么内核(内核加载入内存是启动引导程序 GRUB 调用的,并不存在硬盘驱动不识别的问题)在加载根目录之前是需要加载 SCSI 硬盘或 LVM 文件系统的驱动的。
SCSI 硬盘和 LVM 文件系统的驱动都放在硬盘的 /lib/moles/ 目录中,既然内核没有办法识别 SCSI 硬盘或 LVM 文件系统,那怎么可能读取 /lib/moles/ 目录中的驱动呢?Linux 给出的解决办法是使用 initramfs 这个虚拟文件系统来处理这个问题。
initramfe虚拟文件系统
CentOS 6.x 中使用 initramfs 虚拟文件系统取代了 CentOS 5.x 中的 initrd RAM Disk。它们的作用类似,可以通过启动引导程序加载到内存中,然后会解压缩并在内存中仿真成一个根目录,并且这个仿真的文件系统能够提供一个可执行程序,通过该程序来加载启动过程中所需的内核模块,比如 USB、SATA. SCSI 硬盘的驱动和 LVM、RAID 文件系统的驱动。
也就是说,通过 initramfs 虚拟文件系统在内存中模拟出一个根目录,然后在这个模拟根目录中加载 SCSI 等硬件的驱动,就可以加载真正的根目录了,之后才能调用 Linux 的第一个进程 /sbin/init。
Initramfs 虚拟文件系统主要有以下优点:
initramfs 随着其中数据的増减自动増减容量。
在 initramfs 和页面缓存之间没有重复数据。
initramfs 重复利用了 Linux caching 的代码,因此几乎没有増加内核尺寸,而 caching 的代码已经经过良好测试,所以 initramfs 的代码质量也有保证。
不需要额外的文件系统驱动。
其实大家只需要知道 initramfs 是为了在内核中建立一个模拟根目录,这个模拟根目录是为了可以调用 USB、SATA、SCSI、LVM、RAID 等硬盘接口或文件系统的驱动模块,加载了驱动模块后才可以加载真正的系统根目录。我们可以通过示意图 1 来表示这个过程。
[root@localhost~]#mkdir/tmp/initramfs
#建立测试目录
[root@localhost~]#cp/boot/
initramfs-2.6.32-279.el6.i686.img/tmp/initramfs/
#复制initramfs文件
[root@localhost~]#cd/tmp/initramfs/
[root@localhostinitramfs]#file
initramfs-2.6.32-279.el6.i686.img
initramfe-2.6.32-279.el6.i686.img:gzipcompressed
data,fromUnix,lastmodified:
WedApr1021:49:342013,maxcompression
#查看文件类型,发现这个文件是一个使用gzip命令打包的压缩包
[root@localhostinitramfs]#mvinitramfs-2.6.32-279.el6.i686.imginitramfs-2.6.32-279.el6.i686.img.gz
#修改文件的扩展名为.gz
[root@localhostinitramfs]#gunzip
initramfs-2.6.32-279.el6.i686.img.gz
#解压缩
[root@localhostinitramfs]#ls
initramfs-2.6.32-279.el6.i686.img
[root@localhostinitramfs]#file
initramfs-2.6.32-279.el6.i686.img
initramfe-2.6.32-279.el6.i686.img:ASCIIcpioarchive(SVR4withnoCRC)
#查看文件类型,使用cpio命令的压缩文件
[root@localhostinitramfs]#cpio-ivc<initramfs-2.6.32-279.el6.i686.img
#解压缩
[root@localhostinitramfs]#ll
总用量34512
drwxr-xr-x.2rootroot40964月2412:10bin
drwxr-xr-x.2rootroot40964月2412:10cmdline
drwxr-xr-x.3rootroot40964月2412:10dev
-rw-r--r--.1rootroot194月2412:10dracut-004-283.el6
drwxr-xr-x.2rootroot40964月2412:10emergency
drwxr-xr-x.7rootroot40964月2412:10etc
-rwxr-xr-x.1rootroot89624月2412:10init
drwxr-xr-x.2rootroot40964月2412:10initqueue
drwxr-xr-x.2rootroot40964月2412:10initqueue-finished
drwxr-xr-x.2rootroot40964月2412:10initqueue-settled
drwxr-xr-x.2rootroot40964月2412:10
initqueue-timeout
-rw-r--r--.1rootroot352353284月2412:09initramfs-2.6.32-279.el6.i686.img
drwxr-xr-x.9rootroot40964月2412:10lib
…省略部分输出…
#这就是initramfs虚拟文件系统中的内容,和根目录是不是很像
关机或者某些进程停止,对应的内核模块就会结束。更多知识请网络《Linux就该这么学》
⑺ 如何在编译后,指定安装路径
1. 安装目录变量
在Makefile中,安装目录同样需要使用变量来指定,这样就可以很方便的修汪瞎改文件的安装路径。安装目录的标准命名下边将一一介绍。这些变量基于标准的文件系统结构,这些变量的变种在SVR4、4.4BSD、Linux、Ultrix v4以及其它现代操作系统中都有使用。
安装者希望在调用make是改变这些值,(例如 make prefix=/usr install),或者在配置时改变困弊空这些值(例如 configure –prefix=/usr)。GNU包不会对在该系统上这些变量适合于哪些值做任何猜想,或者说GNU包不会猜测这些包应该被安装到哪里是更合适的:GNU包使用缺省的特定设置是为了以便于所有的GNU包行为一致,它允许安装者做任何自己想要的布局。
以下所罗列的两个变量是指定安装文件的根目录。所有其它安装目录都是它们的子目录。注意:文件不能直接安装在这两个目录下。
prefix
这个变量(通常作为实际文件安装目录的父目录,可以理解为其它实际文件安装目录的前缀)用于构造下列(除这两个安装根目录以外的其它目录变量)变量的缺省值。变量“prefix”缺省值是“/usr/local”。创建完整的GNU系统时,变量prefix的缺省值是空值,“/usr”是“/”的符号连接符文件。(如果使用“Autoconf”工具,它应该写成“@prefix@”)。注意:当更改了变量“prefix”以后重新执行“make install”,不会导致可执行程序(终极目标)的重建。
exec_prefix
这个前缀用于构造下列变量的缺省值。变量“exec_prefix”缺省值是“$(prefix)”(如果使用“Autoconf”工具,它应该写为“@exec_prefix@”)。通常,“$(exec_prefix)”目录中的子目录下存放和机器相关文件(例如可执行文件和例程库)。“$(prefix)”目录的子目录存放通用的一般文件。同样:改变“exec_prefix”的值之后执行“make install”,不会重建可执行程序(终极目标)。
文件(包括可执行程序、说明文档等)的安装目录:
bindir
用于安装一般用户可运行的可执行程序。通常它的值为:“/usr/local/bin”,使用时应写为:“$(exec_prefix)/bin”。(使用“Autoconf”工具时,应该为“@bindir@”)
sbindir
安装可在shell中直接调用执行的程序。这些命令仅对系统管理员有用(系统管理工具)。通常它的值为:“/usr/local/sbin”,要求在使用时应写为:“$(exec_prefix)/sbin”。(使用“Autoconf”工具时,应该为“@sbindir@”)
libexecdir
用于安装那些通常不是由用户直接使用,而是由其它程序调用的可执行程序。通常它的值为:“/usr/local/libexec”,要求在使用时应写为:“$(exec_prefix)/libexec”。(使用“Autoconf”工具时,应该为“@libexecdir@”)
程序执行时使用的数据文件可从以下两个方面来分类:
1. 是否可由程序更改。分为两类:程序可修改和不可修改的文件(虽然用户可编辑其中某些文件)。
2. 是否和体系结构相关。分为两类:体系结构无关文件,可被所有类型的机器共享;体系结构相关文件,仅可被相同类型机器、操作系统共享;其它的就是那些不能被任何两个机器共享的文件。
这样就存在六种不同的可卜含能。除编译生成的目标文件(.o文件)和库文件以外,不推荐使用那些和特定机器体系结构相关的文件,使用和体系无关的数据文件更加简洁,而且,它的实现也并不非常困难。
在Makefile中应该使用以下变量为不同类型的文件指定对应的安装目录:
`datarootdir'
The root of the directory tree for read-only architecture-independent data files. This should normally be /usr/local/share, but write it as $(prefix)/share. (If you are using Autoconf, write it as `@datarootdir@'.) `datadir''s default value is based on this variable; so are `infodir', `mandir', and others.
Datarootdir
机器体系结构无关的只读数据文件的根目录。通常它的值为:“/usr/local/share”,使用时应写为:“$(prefix)/share”。(使用“Autoconf”工具时,应该为“@datarootdir@”)。‘datadir’的缺省值是基于这个变量的,`infodir', `mandir'等其它变量的值也是如此。
datadir
用于安装和机器体系结构无关的只读数据文件。通常它的值与’datarootdir’一样,但是我们使用两个变量是为了用户能够移动一些程序特定的文件而不修改如man 文件、info文件的路径。通常它的值为:“/usr/local/share”,使用时应写为:“$(prefix)/share”。(使用“Autoconf”工具时,应该为“@datadir@”)。“$(infodir)”和“$(includedir)”作为例外情况,参考后续对它们的详细描述。
Datadir的定义对所有包都一样,因此你应该安装你的数据在它的子目录下。大部分包安装它们的数据在如此目录下:$(datadir)/package-name/.
sysconfdir
用于安装从属于特定机器的只读数据文件,包括:主机配置文件、邮件服务、网络配置文件、“/etc/passwd”文件等。所有该目录下的文件都应该是普通文本文件(可识别的“ASCII”码文本文件)。通常它的值为:“/usr/local/etc”,在使用时应写为:“$(prefix)/etc”。(使用“Autoconf”工具时,应该为“@sysconfdir@”)。
不要将可执行文件安装在这个目录下(可执行文件的安装目录应该是“$(libexecdir)”或者“$(sbindir)”)。也不要在这个目录下安装那些需要更改的文件(系统的配置文件等)。这些文件应该安装在目录“$(localstatedir)”下。
sharedstatedir
用于安装那些可由程序运行时修改的文件,这些文件与体系结构无关。通常它的值为:“/usr/local/com”,要求在使用时应写为:“$(prefix)/com”。(使用“Autoconf”工具时,应该为“@sharedstatedir@”)
localstatedir
用于安装那些可由程序运行时修改的文件,但这些文件和体系结构相关。用户没有必要通过直接修改这些文件来配置软件包,对于不同的配置文件,将它们放在“$(datadir)”或者“$(sysconfdir)”目录中。“$(localstatedir)”值通常为:“/usr/local/var”,在使用时应写为:“$(prefix)/var”。(使用“Autoconf”工具时,应该为“@localstatedir@”)
libdir
用于存放编译后的目标文件(.o)文件库文件(文档文件或者执行的共享库文件)。不要在此目录下安装可执行文件(可执行文件应该安装在目录“$(libexecdir)”下)。变量libdir值通常为:“/usr/local/lib”,使用时应写为:“$(exec_prefix)/lib”。(使用“Autoconf”工具时,应该为“@libdir@”)
infodir
用于安装软件包的 Info 文件。它的缺省值为:“/usr/local/info”,使用时应写为:“$(prefix)/info”。(使用“Autoconf”工具时,应该为“@infodir@”)
lispdir
用于安装软件包的Emacs Lisp 文件的目录。它的缺省值为:“/usr/local/share/emacs/site-lisp”,使用时应写为:“$(prefix)/share/emacs/site-lisp”。当使用Autoconf工具时,应将写为“@lispdir@”。为了保证“@lispdir@”能够正常工作,需要在“configure.in”文件中包含如下部分:
lispdir='${datadir}/emacs/site-lisp'
AC_SUBST(lispdir)
includedir
用于安装用户程序源代码使用“#include”包含的头文件。它的缺省值为:“/usr/local/include”,使用时应写为:“$(prefix)/include”。(使用“Autoconf”工具时,应该为“@includedir@”)。
除gcc外的大多数编译器不会在目录“/usr/local/include”中搜寻头文件,因此这种方式只适用gcc编译器。这一点应该不是一个问题,因为很多情况下一些库需要gcc才能工作。对那些依靠其它编译器的库文件,需要将头文件安装在两个地方,一个由变量“includedir”指定,另一个由变量“oldincludedir”指定。
oldincludedir
它所指定的目录也同样用于安装头文件,这些头文件用于非gcc的编译器。它的缺省值为:“/usr/include”。(使用“Autoconf”工具时,应该为“@oldincludedir@”)。
Makefile在安装头文件时,需要判断变量“oldincludedir”的值是否为空。如果为空,就不使用它进行头文件的安装(一般是安装完成“/usr/local/include”下的头文件之后才安装此目录下的头文件)。
一个软件包的安装不能替换该目录下已经存在的头文件,除非是同一个软件包(重新使用相同的软件包在此目录下安装头文件)。例如,软件包“Foo”需要在“oldincludedir”指定的目录下安装一个头文件“foo.h”时,可安装的条件为:1.目录“$(oldincludedir)”目录下不存在头文件“foo.h”;2. 已经存在头文件“foo.h”,存在的头文件“foo.h”是之前软件包“Foo”安装的。
检查头文件“foo.h”是否来自于软件包Foo,需要在头文件的注释中包含一个“magic”字符串,使用命令“grep”来在该文件中查找这个magic。
`docdir'
The directory for installing documentation files (other than Info) for this package. By default, it should be /usr/local/share/doc/yourpkg, but it should be written as $(datarootdir)/doc/yourpkg. (If you are using Autoconf, write it as `@docdir@'.) The yourpkg subdirectory, which may include a version number, prevents collisions among files with common names, such as README.
这个目录安装除了Info外的该包提供的文档,它的缺省值/usr/local/share/doc/yourpkg,使用时应写为:“$(datarootdir)/doc/yourpkg”。(使用“Autoconf”工具时,应该为“@docdir@”)。Yourpkg子目录可能包括版本号,为了阻止具有相同文件名字的文件冲突,例如README。
`infodir'
The directory for installing the Info files for this package. By default, it should be, but it should be written as (If you are using Autoconf, write it as `@infodir@'.) infodir is separate from docdir for compatibility with existing practice.
这个目录安装该包的info文件。它的缺省值是:/usr/local/share/info, 使用时应写成:$(datarootdir)/info.(使用“Autoconf”工具时,应该为“@infodir@”).infodir从docdir中单独分离出来为了兼容已经存在的practice。
`htmldir'
`dvidir'
`pdfdir'
`psdir'
Directories for installing documentation files in the particular format. (It is not required to support documentation in all these formats.) They should all be set to $(docdir) by default. (If you are using Autoconf, write them as `@htmldir@', `@dvidir@', etc.) Packages which supply several translations of their documentation should install them in `$(htmldir)/'ll, `$(pdfdir)/'ll, etc. where ll is a locale abbreviation such as `en' or `pt_BR'.
这些目录用于安装特定格式的文档(并不要求支持所有这些格式的文档)。缺省值应该设置为:$(docdir)(使用“Autoconf”工具时,应该为“@htmldir @”等)。
`libdir'
The directory for object files and libraries of object code. Do not install executables here, they probably ought to go in $(libexecdir) instead. The value of libdir should normally be /usr/local/lib, but write it as $(exec_prefix)/lib. (If you are using Autoconf, write it as `@libdir@'.)
`lispdir'
The directory for installing any Emacs Lisp files in this package. By default, it should be /usr/local/share/emacs/site-lisp, but it should be written as $(datarootdir)/emacs/site-lisp.
If you are using Autoconf, write the default as `@lispdir@'. In order to make `@lispdir@' work, you need the following lines in your configure.in file:
lispdir='${datarootdir}/emacs/site-lisp'
AC_SUBST(lispdir)
`localedir'
The directory for installing locale-specific message catalogs for this package. By default, it should be /usr/local/share/locale, but it should be written as $(datarootdir)/locale. (If you are using Autoconf, write it as `@localedir@'.) This directory usually has a subdirectory per locale.
这个目录安装该包用于本地特定消息的目录。缺省值是:/usr/local/share/locale, 但是应该写成:`@localedir@'。这个目录常常对每个locale(本地化)都有一个子目录。
⑻ 如何查看/etc/passwd文件以冒号分隔的第二列的所有内容
1)“用户名”是代表用户账号的字符串。通常长度不超过8个字符,并且由大小写字母和/或数字组成。登录名中不能有冒号(,因为冒号在这里是分隔符。为了兼容起见,登录名中最好不要包含点字符(.),并且不使用连字符(-)和加号(+)打头。
2)“口令”一些系统中,存放着加睁笑密后的用户口令字。。虽然这个字段存放的只是用户口令的加密串,不是
明文,但是由于/etc/passwd文件对所有用户都可读,所以这仍是一个安全隐患。因此,现在许多 Linux
系统(如SVR4)都使用了shadow技术,把真正的加密后的用户口令字存放到/etc/shadow文件中,而在/etc/passwd文件的口令字
段中只存放一个特殊的字符,例如“x”或者“*”。
3)“用户标识号”是一个整数,系统内部用它来标识用户。一般情况下它与用户名是一一游行对应的。如果几个用悉磨含户名对应的用户标识号是一样的,系统内部将把它们视为同一个用户,但是它们可以有不同的口令、不同的主目录以及不同的登录Shell等。
通常用户标识号的取值范围是0~65 535。0是超级用户root的标识号,1~99由系统保留,作为管理账号,普通用户的标识号从100开始。在Linux系统中,这个界限是500。
4)“组标识号”字段记录的是用户所属的用户组。它对应着/etc/group文件中的一条记录。
⑼ Linux里面什么是ext2fs
EXT2FS第二代扩展文件系统(英语:second extended filesystem,缩写为 ext2),是LINUX内核所用的文件系统。它开始由Rémy Card设计,用以代替ext,于1993年1月加入linux核心支持之中。ext2 的经典实现为LINUX内核中的ext2fs文件系统驱动,最大可支持2TB的文件系统,至linux核心2.6版时,扩展到可支持32TB。其他的实现包括GNU Hurd,Mac OS X(第3方),Darwin(第3方),BSD。ext2为数个LINUX发行版的默认文件系统,如Debian、Red Hat Linux等 。
简介
其单一文件大小与文件系统本身的容量上限与文件系统本身的簇大小有关,在一般常见的 x86电脑系统中,簇最大为 4KB, 则单一文件大小上限为 2048GB, 而文件系统的容量上限为 16384GB。
但由于目前核心 2.4 所能使用的单一分割区最大只有 2048GB,实际上能使用的文件系统容量最多也只有 2048GB。
至于Ext3文件系统,它属于一种日志文件系统,是对ext2系统的扩展。它兼容ext2,并且从ext2转换成ext3并不复杂。
Ext2文件系统具有以下一般特点:
1、当创建Ext2文件系统时,系统管理员可以根据预期的文件平均长度来选择最佳的块大小(从1024B——4096B)。例如,当文件的平均长度小于几千字节时,块的大小为1024B是最佳的,因为这会产生较少的内部碎片——也就是文件长度与存放块的磁盘分区有较少的不匹配。另一方面,大的块对于 大于几千字节的文件通常比较合合适,因为这样的磁盘传送较少,因而减轻了系统的开销[1]。
2、当创建Ext2文件系统时,系统管理员可以根据在给定大小的分区上预计存放的文件数来选择给该分区分配多少个索引节点。这可以有效地利用磁盘的空间。
3、文件系统把磁盘块分为组。每组包含存放在相邻磁道上的数据块和索引节点。正是这种结构,使得可以用较少的磁盘平均寻道时间对存放在一个单独块组中的文件并行访问。
4、在磁盘数据块被实际使用之前,文件系统就把这些块预分配给普通文件。因此当文件的大小增加时,因为物理上相邻的几个块已被保留,这就减少了文件的碎片。
5、支持快速符号链接。如果符号链接表示一个短路径名(小于或等于60个字符),就把它存放在索引节点中而不用通过由一个数据块进行转换。
Ext2还包含了一些使它既健壮又灵活的特点:
1、文件更新策略的谨慎实现将系统崩溃的影响减到最少。我们只举一个例子来体现这个优点:例如,当给文件创建一个硬链接时,首先增加磁盘索引节点中 的硬链接计数器,然后把这个新的名字加到合适的目录中。在这种方式下,如果在更新索引节点后而改变这个目录之前出现一个硬件故障,这样即使索引节点的计数 器产生错误,但目录是一致的。因此,尽管删除文件时无法自动收回文件的数据块,但并不导致灾难性的后果。如果这种处理的顺序相反(更新索引节点前改变目 录),同样的硬件故障将会导致危险的不一致,删除原始的硬链接就会从磁盘删除它的数据块,但新的目录项将指向一个不存在的索引节点。如果那个索引节点号以 后又被另外的文件所使用,那么向这个旧目录的写操作将毁坏这个新的文件。
2、在启动时支持对文件系统的状态进行自动的一致性检查。这种检查是由外部程序e2fsck完成的,这个外部程序不仅可以在系统崩溃之后被激活,也 可以在一个预定义的文件系统安装数(每次安装操作之后对计数器加1)之后被激活,或者在自从最近检查以来所花的预定义时间之后被激活。
3、支持不可变(immutable)的文件(不能修改、删除和更名)和仅追加(append-only)的文件(只能把数据追加在文件尾)。
4、既与Unix System V Release 4(SVR4)相兼容,也与新文件的用户组ID的BSD语义相兼容。在SVR4中,新文件采用创建它的进程的用户组ID;而在BSD中,新文件继承包含它 的目录的用户组ID。Ext2包含一个安装选项,由你指定采用哪种语义。
即使Ext2文件系统是如此成熟、稳定的程序,也还要考虑引入另外几个负面特性。目前,一些负面特性已新的文件系统或外部补丁避免了。另外一些还仅仅处于计划阶段,但在一些情况下,已经在Ext2的索引节点中为这些特性引入新的字段。最重要的一些特点如下:
块片(block fragmentation)
系统管理员对磁盘的访问通常选择较大的块,因为计算机应用程序常常处理大文件。因此,在大块上存放小文件就会浪费很多磁盘空间。这个问题可以通过把几个文件存放在同一块的不同片上来解决。
透明地处理压缩和加密文件
这些新的选项(创建一个文件时必须指定)将允许用户透明地在磁盘上存放压缩和(或)加密的文件版本。
逻辑删除
一个undelete选项将允许用户在必要时很容易恢复以前已删除的文件内容。
日志
日志避免文件系统在被突然卸载(例如,作为系统崩溃的后果)时对其自动进行的耗时检查。
实际上,这些特点没有一个正式地包含在Ext2文件系统中。有人可能说Ext2是这种成功的牺牲品;直到几年前,它仍然是大多数Linux发布公司采用的首选文件系统,每天有成千上万的用户在使用它,这些用户会对用其他文件系统来代替Ext2的任何企图产生质疑。
Ext2中缺少的最突出的功能就是日志,日志是高可用服务器必需的功能。为了平顺过渡,日志没有引入到Ext2文件系统;但是,我们在后面 “Ext3文件系统”中会讨论,完全与Ext2兼容的一种新文件系统已经创建,这种文件系统提供了日志。不真正需要日志的用户可以继续使用良好而老式的Ext2文件系统,而其他用户可能采用这种新的文件系统。现在发行的大部分系统采用Ext3作为标准的文件系统。
Linux支持多种不同类型的文件系统:网络文件系统NFS,磁盘文件系统Extfs,特殊文件系统proc、tmpfs等。
Ext2fs文件系统基本概念
Inode
Ext2fs中,每个文件都用如下图所示的inode结构来描述,用户空间操作的对象是文件路径和名称,系统kernel把路径名称解析成inode,通过inode号来访问它代表的文件。
Mode:包含两个数据,文件类型(普通文件/目录/字符设备/块设备/符号链接/管道)和用户访问权限信息(0660)。
Ownerinfo:文件属组信息。
Size:文件长度,单位是byte。
Timestamps:文件访问和修改的时间戳。
Linkscount:这个项在上图中没有体现,它记录了这个inode存在多少个链接,创建新文件时,其inode的linkscount应该为1,文件被删除后,这个inode的linkscount就变为0。
DataBlocks:指向真实的文件数据块,因为大文件可能会分配很多的block,直接在inode中保存所有的数据块指针将会比较困难,也会浪费掉很多空间,毕竟系统中大文件的数量是占少数的,所以设计了间接块指针(Indirectblocks)和二级块指针(Doubleblocks)来指向真实数据块。
实际上还应该包含了inode号。
目录
在Ext2fs中,目录被看做一种特殊文件,也用一个inode来描述,目录的datablock中保存了目录下的所有内容,每条内容叫做一个entry,结构如下:
每条entry都保存了inode号、entry的长度、文件名长度、文件类型,并且都是4字节对齐。
特别地,每个目录下有两个特殊的子目录,'.'和'..',分别代表当前目录和上一级目录,这两个目录文件其实是硬链接。其中'..'有一个重要的作用:FSchecker(可以把文件系统umount后手动执行e2fsck看看)在检查文件系统的时候,就会使用’..‘来检查目录是否可以追溯到挂载根目录,如果检查失败,目录便会被链接到挂载根目录下面的lost+found。
链接
为了方便系统内文件共享,Linux支持了两种基本的链接文件:硬链接和软链接(也叫符号链接)。
硬链接并不是一个独立的文件,不占用inode,只是在目录下创建了一条entry,其中inode号保存的是目标文件的inode号,访问硬链接时,文件系统通过inode将访问操作重定向到目标文件,实现了文件共享,所以硬链接就是多个文件名直接指向同一个inode,用stat命令也能看到其inode号就是目标文件的inode号,它的特点:
不能跨文件系统。
目标文件必须先存在(inode存在且linkcount不为0)。
只能对普通文件创建硬链接,目录不行。
删除一个硬链接文件并不影响其他有相同inode号的文件。
软链接是一个独立的文件,拥有自己的inode,其数据块存放的是目标文件的名称,访问软链接时,kernel先访问软链接的内容,拿到目标文件名,并重新启动路径解析,获取到目标文件inode号再向文件系统发起访问。软链接的特点:
可以跨文件系统。
文件和目录都可以。
可对不存在的文件或目标创建软链接。
软链接有自己文件属性和权限。
创建软链接时,链接计数i_nlink不会增加;
删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即danglinglink,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。
软链接的目标文件也可以是软链接,其解析过程是递归的。
注意:软链接创建时目标文件的路径指向使用绝对路径比较好,使用相对路径创建的软链接被移动后该软链接文件将成为一个死链接,因为链接数据块中记录的也是相对路径指向。
下面这个图清晰描述了硬链接和软连接之间的区别:
Ext2fs基本结构
在创建文件系统的时候,Ext2fs将设备(磁盘或者分区)划分成1K、2K或者4K的block,然后通过Blockgroup来管理,Ext2fs/Ext3fs/Ext4fs的结构差不多(Ext2fs主要是少了日志功能相关的内容),大致如下图所示:
SuperBlock
SuperBlock是文件系统最重要的数据,它从设备开始位置偏移1024字节的地方开始存储,占用1个block。如果block的大小是1KB,那么SuperBlock就存放在block-1。如果block的大小是4KB,那Superblock就存放在block-0。
在Ext2fs的第一个版本(reverson0),每个BlockGroup都会存储一份SuperBlock的一份副本,因为对空间浪费比较严重,后来的版本就只在部分BlockGroup(0、1、3、5、7、9这几个group)中保留了SuperBlock的副本,在这几个Group,和SuperBlock一起备份的还有GroupDescriptor。当然,如果没有这么多Group,副本数量自然更少,在后面的demo中也可以看出来。其中Group-0中的SuperBlock叫作PrimarySuperBlock,文件系统被mount时,VFS读取的也正是这份。
SuperBlock里面的具体数据包括:
inode和block的总数,以及还有多少未分配。
每个BlockGroup有多少个inode和block。
文件系统唯一身份标识符(UUID),每个设备上的文件系统UUID都不一样。
...
GDT
GroupDescriptorTable,GDT在文件系统中的layout紧跟Superblock后面,是文件系统第二关键的数据,它主要用于存放所有BlockGroup的信息:
Ext2fs为GDT预留了一部分空间,用于文件系统扩容。
通过冗余提高了文件系统可靠性:在多个group中保存了关键数据的冗余副本,包括superblock、GDT,当这些关键数据损坏的时候,很容易从这些冗余副本中恢复。
提升性能:分成group后,inodetable和datablock之间的”距离“变近了,在执行I/O时,可能会减少磁头寻址的时间。
注:实际上inodesize,每个group中的block数等参数都可以在创建文件系统的时候指定,具体命令参数参考manpage。
Ext2fs的性能优化
为了提升I/O性能,Ext2fs内核代码也做了很多设计,其中有两个关键的技术:
提前读:当必须读取一个块时,内核代码在几个连续的块上请求I/O。通过这种方式,它试图确保要读取的下一个块已经加载到缓冲区缓存中。提前读通常在文件的连续读取期间执行,Ext2fs将它们扩展到目录读取,可以是显式读取(readdir(2)调用),也可以是隐式读取(namei内核目录查找)。
预分配:在将数据写入文件时,Ext2fs在分配新块时预先分配最多8个相邻块。具体预分配多少个块取决于blocksize:blocksize=1KB,每次预分配2个block;blocksize=2KB,每次预分配4个block;blocksize=4KB,每次预分配8个block。当然,对于用touch创建的空文件是不会预分配block的。即使在非常满的文件系统上,预分配命中率也只有75%左右。这种预分配在负载较大的情况下可以获得良好的写性能,同时它还允许将连续的块分配给文件,从而加快未来的顺序读取。
下面是Ext2fs、Ext3fs和Ext4fs的一个简单对比:
只有Ext2fs的Filesystemstate是notclean,Ext3fs和Ext4fs都是clean,Ext2fs刚被以读写模式mount时,这个state被设置成notclean,umount或者以只读模式mount时,state被设置成clean,启动时文件系统根据这个状态来决定是否要执行检查。
Ext3fs/Ext4fs的Superblock中多了关于日志功能的信息。
Ext4fs的每个group多了校验和(checksum)数据。
⑽ 如何编写Linux Daemon后台程序
守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期核瞎模性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进 程。Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任 务。比如,作业规划进程crond,打印进程lpd等。 x0dx0a守护进程的编程本身并不复杂,复杂的是各种版本的Unix的实现机制不尽相同,造成不同Unix环境下守护进程的编程规则并不一致。这需要读者注意,照搬 某些书上的规则(特别是BSD4.3和低版本的System V)到Linux会出现错误的。下面将全面介绍Linux下守护进程的编程要点并给出详细实例。 x0dx0a一. 守护进程及其特性 x0dx0a守护进程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的 文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守 护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端 (通常是shell)执行。 x0dx0a总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果读者对进程有比较深入的认识就更容易理解和编程了。 x0dx0a二. 守护进程的编程要点 x0dx0a前面讲过,不同Unix环境下守护进程的编程规则并不一致。所幸的是守护进程的编程原则其实都一样,区别在于具体的实现细节不同。这个原则就是要满足守护 进程的特性。同时,Linux是基于Syetem V的SVR4并遵循Posix标准,实现起来与BSD4相比更方便。编程要点如下; x0dx0a1. 在后台运行。 x0dx0a为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。改缓 x0dx0aif(pid=fork()) x0dx0aexit(0);//是父进程,结束父进程,子进程继续 x0dx0a2. 脱离控制终端,登录会话和进程组 x0dx0a有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。 x0dx0a控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长: x0dx0asetsid(); x0dx0a说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。 x0dx0a3. 禁止进程重新打开控制终端 x0dx0a现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端: x0dx0aif(pid=fork()) x0dx0aexit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长) x0dx0a4. 关闭打开的文件描述符 x0dx0a进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关神郑闭它们: x0dx0afor(i=0;i 关闭打开的文件描述符close(i);> x0dx0afor(i=0;i< NOFILE;++i)x0dx0a5. 改变当前工作目录 x0dx0a进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/") x0dx0a6. 重设文件创建掩模 x0dx0a进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0); x0dx0a7. 处理SIGCHLD信号 x0dx0a处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为 僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将 SIGCHLD信号的操作设为SIG_IGN。 x0dx0asignal(SIGCHLD,SIG_IGN); x0dx0a这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。 x0dx0a三. 守护进程实例 x0dx0a守护进程实例包括两部分:主程序test.c和初始化程序init.c。主程序每隔一分钟向/tmp目录中的日志test.log报告运行状态。初始化程序中的init_daemon函数负责生成守护进程。读者可以利用init_daemon函数生成自己的守护进程。 x0dx0a1. init.c清单 x0dx0a#include < unistd.h > x0dx0a#include < signal.h > x0dx0a#include < sys/param.h > x0dx0a#include < sys/types.h > x0dx0a#include < sys/stat.h > x0dx0avoid init_daemon(void) x0dx0a{ x0dx0aint pid; x0dx0aint i; x0dx0ax0dx0aif(pid=fork()) x0dx0aexit(0);//是父进程,结束父进程 x0dx0aelse if(pid< 0) x0dx0aexit(1);//fork失败,退出 x0dx0a//是第一子进程,后台继续执行 x0dx0ax0dx0asetsid();//第一子进程成为新的会话组长和进程组长 x0dx0a//并与控制终端分离 x0dx0aif(pid=fork()) x0dx0aexit(0);//是第一子进程,结束第一子进程 x0dx0aelse if(pid< 0) x0dx0aexit(1);//fork失败,退出 x0dx0a//是第二子进程,继续 x0dx0a//第二子进程不再是会话组长 x0dx0ax0dx0afor(i=0;i< NOFILE;++i)//关闭打开的文件描述符 x0dx0aclose(i); x0dx0achdir("/tmp");//改变工作目录到/tmp x0dx0aumask(0);//重设文件创建掩模 x0dx0areturn; x0dx0a} x0dx0a2. test.c清单 x0dx0a#include < stdio.h > x0dx0a#include < time.h > x0dx0avoid init_daemon(void);//守护进程初始化函数 x0dx0amain() x0dx0a{ x0dx0aFILE *fp; x0dx0atime_t t; x0dx0ainit_daemon();//初始化为Daemon x0dx0awhile(1)//每隔一分钟向test.log报告运行状态 x0dx0a{ x0dx0asleep(60);//睡眠一分钟 x0dx0aif((fp=fopen("test.log","a")) >=0) x0dx0a{ x0dx0at=time(0); x0dx0afprintf(fp,"I'm here at %sn",asctime(localtime(&t)) ); x0dx0afclose(fp); x0dx0a} x0dx0a} x0dx0a} x0dx0a以上程序在RedHat Linux6.0下编译通过。步骤如下: x0dx0a编译:gcc _g _o test init.c test.c x0dx0a执行:./test x0dx0a查看进程:ps _ef x0dx0a从输出可以发现test守护进程的各种特性满足上面的要求。