学习的最高境界是将学过的东西忘得一干二净! 剩下的便是精髓!
Linux Shell
Linux初学者Patch使用指南
简介
本文的目的是向Linux新手介绍一种无价的资源,Larry Wall的patch程序。patch是用来查找文件之间差异的GNU diff命令的一个接口;diff有很多选项,但是该命令最常用的用途是用来生成一个文件,该文件中列出了内容发生改变的行,显示两个原始文件、修改过的行以及由于内容没有变化而忽略掉的行。patch典型地用于把一个目录下的源代码文件更新到新的版本,从而就避免了下载整个新的源代码档案的必要。下载一个有效的patch仅仅需要下载发生变化的那些代码行就可以了。
patch最初源自十年前,那时网络带宽的限制促进了patch的发展,然而和当时的很多Unix工具一样,直到现在,patch还在广泛应用。在Dr. Dobb之旅的2月份的程序员杂志中,Larry Wall对早期的patch做了一些很有趣的说明:
DDJ:顺便问一下,patch和diff哪个出现的早?
LW:从很长一段时间来说,diff出现地比较早。我想diff大约比patch早10年出现,一回想起来,我就纳闷为什么没有人早些想到使用patch呢?
但是我想我知道这中间的原因。这很大程度上是心理因素使然。当开发出diff时,程序员增加了一个e选项,我想就是这个选项的原因,该选项后来滋生为一个ed脚本,因此大家都会对自己说,"嗯,如果我想自动使用diff,那么我就使用这个选项。"因此从来都没有人编写一个计算机程序来获取其它格式的输出并使用这些结果。或者是那些设计diff的人员,或者是那些使用diff格式而受益的人员太沉迷其中了,因为你可以对那些已经修改过的内容使用diff操作并让这些内容正常工作都是很容易的。
现在回想起来,这个问题是显而易见的。但是平心而论,与其说这是一个天才的灵感的闪现,还不如说这是自信心的体现。我开发出rn的第一个版本,然后继续为它编写补丁,这整个事情就是一团乱麻。你不可能强制用户使用补丁,因为他们可以手工完成这些工作。因此,他们就会省略一些自己认为不必要的工作,他们把新的修改加诸于原来的程序之上,因此而使得程序混乱。我编写补丁,这样就没有人找借口说这很难了。
我不清楚是否事实就是如此,但是多年以来,我一直对别人讲patch对于计算机文化的影响比rn和Perl的影响都要大。现在Internet的速度比原来有大幅度的提高,把整个发行版本分散到世界各地也变得更加简单,似乎只有在开发者之间才需要传送补丁。我已经很多年没有传送Perl的patch工具包了。我认为虽然patch整体上的重要性在逐渐降低,但是仍然是开发者交流思想的一种方法。但是就那一段时间而言,patch真正在相当大的程度上都影响了软件的开发方式。
Larry Wall针对patch对于计算机业界总体上重要性正在降低的评价可能是正确的,但是在自由软件世界中,patch仍然是一种必不可少的工具。无处不在的patch使得新手和非程序员能够简单地参与软件的alpha测试和beta测试,这对于整个计算机业界是十分有益的。
在我留意到在Linux内核邮件列表中会周期性的出现这样一件事情时就产生了写这篇文章的念头。大约每三个月就会有人张贴要求把Linux内核源代码的发行版本独立出来的文章,据说这是因为有些人只对i386的代码和IDE的磁盘驱动感兴趣,他们并不想为每个内核发行版本都下载Alpha、Sparc等等的文件和众多的SCSI驱动程序。这篇文章后面紧跟的是一些耐心的回复文章(有些文章则并没有耐心),大部分文章都是在讨论原来的使用有关patch来更新内核源代码。接着Linus Torvalds就会再次声明自己没有兴趣投身于这种把内核源程序切割成小块的繁杂的劳动,但是如果有人愿意,他们可以自由地开展这项独立的工程。到现在为止都没有志愿者出现。我并不想谴责那些内核黑客不能耐心等待,却把生活变得复杂;我猜想直接使用内核工作可能比检查整个内核的发行版本方案要更加有趣、更富有挑战性。下载11M的内核源程序包可是件非常耗费时间的事情(对于那些按照时间上网的人来说,这是很昂贵的),但是内核patch才只有几十K大小,很少会超过1M。我的硬盘上的2.1.99开发内核源程序经过patch的升级,已经升级到了2.1.119版本,我怀疑如果我紧随内核的发展而不断升级,那么也许我就要完整地下载每一个发行版本了。
使用patch
patch附带有一个很好的帮助,其中罗列了很多选项,但是99%的时间只要两个选项就能满足我们的需要:
patch -p1 < [patchfile]
patch -R < [patchfile] (used to undo a patch)
-p1选项代表patchfile中文件名左边目录的层数,顶层目录在不同的机器上有所不同。要使用这个选项,就要把你的patch放在要被打补丁的目录下,然后在这个目录中运行path -p1 < [patchfile]。来自Linux内核patch的一个简短的引用可以这样实现:
diff -u --recursive --new-file v2.1.118/linux/mm/swapfile.c linux/mm/swapfile. c--- v2.1.118/linux/mm/swapfile.c Wed Aug 26 11:37:45 1998 +++ linux/mm/swapfile.c Wed Aug 26 16:01:57 1998 @@ -489,7 +489,7 @@
int swap_header_version;
int lock_map_size = PAGE_SIZE;
int nr_good_pages = 0; - char tmp_lock_map = 0; + unsigned long tmp_lock_map = 0;
应用来自本段中使用-p1开关拷贝的patch可以有效地减短patch定位的路径;patch会查找当前目录下一个名为/mm的子目录,接着应该会在这儿发现swapfile.c文件,然后等待打补丁。在这个过程中,以破折号(“-”号,译者注)开始的行会被一个以加号(“+”号,译者注)开始的行代替。一个典型的patch会包含对多个文件的更新,每个部分中都由对两个版本的文件运行diff -u命令的输出结果组成。
patch在操作时把自己的输出结果显示在屏幕上,但是这种输出通常都滚屏太快,来不及观看。原来准备patch的文件名为*.orig,新的patch文件会覆盖这个初始文件名。
打补丁的问题
使用不同版本的patch问题来源可能不同,所有的版本在网络上都是可用的。Larry Wall近年来已经不再做很多工作来更新patch了,这可能是由于他最后发行的一个版本在大部分情况下都能正常运行。最近几年以来,一直是GNU项目的FSF程序员发行新版本的patch。他们首先修订有问题的patch,但是我最近一直使用没有问题的2.5版本(这是Debian2.0的发行版本号)。过去,我的2.1版本也一直运行的很好。当前的GNU patch的版本可以从GNU FTP站点上获取,然而大部分人都只使用他们Linux发行版中所提供的版本。
让我们假定你已经对一个目录下的源程序文件进行了patch修补工作,但是patch并没有清晰地发挥作用。这可能会偶然发生,在打补丁的过程中会显示错误信息,其中带有行号,说明哪一个文件出现了问题。有时错误是很明显的,例如缺少了分号,这种错误可以不费多大力气就能改正。另外一种可能是从patch部分删除了产生问题的部分,但是这样根据所涉及到的文件的不同可能会正常工作,也可能不能正常工作了。
另外一种常见的错位为:假设你有一个未使用tar打包的内核源程序文件,在/linux/arch/下浏览各个子目录时你会发现各种机器体系结构子目录,例如alpah、sparc等等。如果你和大多数Linux用户一样,使用的是Intel的处理器(或者是Intel系列),你可以决定删除这些目录,这些目录对于编译你特殊的内核并不需要,只是白白占用了磁盘空间。一段时间之后发行了一个新的内核patch,此时试图进行patch操作,当它发现不能找到自己打补丁需要的Alpha或者PPC文件,就会停顿下来。幸运的是patch在这些地方允许用户参与,它会询问"Skip this patch?"回答"y",patch就可以按照正确的路径继续执行。也许你需要回答这个问题很多次,因此允许自己不需要的目录保留在磁盘上是一种很好的方法。
给内核打补丁的技巧
很多Linux用户使用patch都主要是给内核源程序打补丁,因此有一些技巧可以使用。可能最简单的方法是使用shell脚本给内核打补丁,这可以在内核源程序树中的/scripts子目录中找到。这种方便的、编写良好的脚本是由Nick Holloway在1995年编写的;两年以后,Adam Sulmicki增加了多种压缩格式的支持,包括*.bz、*.bz2、compress、gzip和无格式文本(也就是已经解压的patch)。这个脚本假定在你使用新版本的patch时,你的内核源程序是在/usr/src/linux目录中。这些缺省值可以通过这种格式的命令行开关覆盖:patch-kernel [sourcedir [patchdir] ]。如果任何一部分的patch失败,对内核打补丁的过程都会失败,但是如果patch清晰地起作用,它就会调用find,这会删除所有的patch留下的*.orig文件。
如果你准备查看命令的输出,或者可能你希望保留*.orig文件直到你确定打过补丁的源程序编译已经通过,按照我的经验,直接运行patch(正如前面介绍的一样,patch位于内核源程序的最高目录)是很可靠的。为了避免对patch进行解压,在使用之前,可以使用这样一个技巧:
gzip -cd patchXX.gz | patch -p1
或者
bzip2 -dc patchXX.bz2 | patch -p1
在使用patch之后,可以使用find程序来检测被拒绝的文件:
find . -name *.rej
第一次使用这个命令,语法可能有些不清楚。点号(“.”)说明find应该查找当前目录并递规查找当前目录之下的所有子目录。记住,点号前后都应该有一个空格。通配符"*"号前面的反斜线把星号转义出来,以免shell会搞混,星号是有其它意义的。如果find找到了任何的*.rej文件,它就会把文件名打印到屏幕上。如果没有任何输出find就退出了,那么就差不多能确定patch正确发挥作用了。
find的另外一个工作是删除*.orig文件:
find . -name *.orig -print0 | xargs -0r rm -f
这个命令敲起来相当麻烦,可以使用一个新的shell别名来代替这个命令。在你的~/.bashrc文件中类似这样的一行:
alias findorig find . -name *.orig -print0 | xargs -0r rm -f
可以允许你只输入findorig就可以调用前面的命令。如果别名命令的定义中包含空格,那么就必须使用单引号。为了不用先退出再重新登陆就可以使用一个新的别名,可以在命令行中敲如~/.bashrc。
附加内容和结束语
在撰写本文时,我刚好把自己的机器从2.1版本使用patch升级到了2.5版本。这两个版本都是来自现在的FSF/GNU维护人员。马上我就注意到2.5版本默认的输出已经改变了,屏幕上显示的信息变少了。原来在patch检测进行修补的行号时显示的Larry Wall的"...hmm"不见了。2.5版本的输出只剩下诸如"patching file [filename]"之类的信息了,而没有早期版本显示的那么多信息了。无可否认,信息滚屏太快,根本无法阅读,但是输出可以重定向到一个文件中供以后使用。这种变化不会影响程序的功能,但是减少了人为的成分。在我看来,使用诸如原来的"...hmm"信息和源代码中的注释一样,对于提醒用户程序是显示执行的工作的结果是很有价值的,这就像人在呼吸一样,而不应该使用一些毫无结果的位集合。通过对patch命令行增加--verbose开关可以恢复原来的显示内容,但是我相信很多用户既不会注意到这个选项,也不会不辞辛劳地输入这个选项。2.1和2.5版本的另外一个不同是除非patch给出了-b选项,否则不能创建*.orig备份文件。
对于那些对软件和内核"前沿"bug报告测试和提供测试报告不感兴趣的人来说,patch并不是必须的,但是通常大部分Linux世界里有趣的开发都是属于这个范畴的。获得patch的使用方式并不困难,这种努力可以得到充分的回报。
FILE STORAGE HARDWARE AND DISK ORGANIZATION
A hard disk is a sealed unit containing a number of platters in a stack. Hard disks may be mounted in a horizontal or a vertical position. In this description, the hard drive is mounted horizontally.
Electromagnetic read/write heads are positioned above and below each platter. As the platters spin, the drive heads move in toward the center surface and out toward the edge. In this way, the drive heads can reach the entire surface of each platter.
On a hard disk, data is stored in thin, concentric bands. A drive head, while in one position can read or write a circular ring, or band called a track. There can be more than a thousand tracks on a 3.5-inch hard disk. Sections within each track are called sectors. A sector is the smallest physical storage unit on a disk, and is almost always 512 bytes (0.5 kB) in size.
The figure below shows a hard disk with two platters.
Figure 3-1 Parts of a Hard Drive

The structure of older hard drives (i.e. prior to Windows 95) will refer to a cylinder/ head/ sector notation. A cylinder is formed while all drive heads are in the same position on the disk. The tracks, stacked on top of each other form a cylinder. This scheme is slowly being eliminated with modern hard drives. All new disks use a translation factor to make their actual hardware layout appear continuous, as this is the way that operating systems from Windows 95 onward like to work.
To the operating system of a computer, tracks are logical rather than physical in structure, and are established when the disk is low-level formatted. Tracks are numbered, starting at 0 (the outermost edge of the disk), and going up to the highest numbered track, typically 1023, (close to the center). Similarly, there are 1,024 cylinders (numbered from 0 to 1023) on a hard disk.
The stack of platters rotate at a constant speed. The drive head, while positioned close to the center of the disk reads from a surface that is passing by more slowly than the surface at the outer edges of the disk. To compensate for this physical difference, tracks near the outside of the disk are less-densely populated with data than the tracks near the center of the disk. The result of the different data density is that the same amount of data can be read over the same period of time, from any drive head position.
The disk space is filled with data according to a standard plan. One side of one platter contains space reserved for hardware track-positioning information and is not available to the operating system. Thus, a disk assembly containing two platters has three sides available for data. Track-positioning data is written to the disk during assembly at the factory. The system disk controller reads this data to place the drive heads in the correct sector position.
A sector, being the smallest physical storage unit on the disk, is almost always 512 bytes in size because 512 is a power of 2 (2 to the power of 9). The number 2 is used because there are two states in the most basic of computer languages - on and off.
Each disk sector is labelled using the factory track-positioning data. Sector identification data is written to the area immediately before the contents of the sector and identifies the starting address of the sector.
The optimal method of storing a file on a disk is in a contiguous series, i.e. all data in a stream stored end-to-end in a single line. As many files are larger than 512 bytes, it is up to the file system to allocate sectors to store the file’s data. For example, if the file size is 800 bytes, two 512 k sectors are allocated for the file.
A cluster can consist of one or more consecutive sectors. The number of sectors is always an exponent of 2. A cluster could consist of 1 sector (2^0), or, more frequently, 8 sectors (2^3). The only odd number a of sectors a cluster could consist of is 1. It could not be 5 sectors or an even number that is not an exponent of 2. It would not be 10 sectors, but could be 8 or 16 sectors.
They are called clusters because the space is reserved for the data contents. This process protects the stored data from being over-written. Later, if data is appended to the file and its size grows to 1600 bytes, another two clusters are allocated, storing the entire file within four clusters.
Figure 3-2 Sectors and Clusters

If contiguous clusters are not available (clusters that are adjacent to each other on the disk), the second two clusters may be written elsewhere on the same disk or within the same cylinder or on a different cylinder - wherever the file system finds two sectors available. A file stored in this non-contiguous manner is considered to be fragmented. Fragmentation can slow down system performance if the file system must direct the drive heads to several different addresses to find all the data in the file you want to read. The extra time for the heads to travel to a number of addresses causes a delay before the entire file is retrieved.
Cluster size can be changed to optimize file storage. A larger cluster size reduces the potential for fragmentation, but increases the likelihood that clusters will have unused space. Using clusters larger than one sector reduces fragmentation, and reduces the amount of disk space needed to store the information about the used and unused areas on the disk.
Most disks used in personal computers today rotate at a constant angular velocity. The tracks near the outside of the disk are less densely populated with data than the tracks near the center of the disk. Thus, a fixed amount of data can be read in a constant period of time, even though the speed of the disk surface is faster on the tracks located further away from the center of the disk.
Modern disks reserve one side of one platter for track positioning information, which is written to the disk at the factory during disk assembly. It is not available to the operating system. The disk controller uses this information to fine tune the head locations when the heads move to another location on the disk. When a side contains the track position information, that side cannot be used for data. Thus, a disk assembly containing two platters has three sides that are available for data.
The Master Boot Record, created when you create the first partition on the hard disk, is probably the most important data structure on the disk. It is the first sector on every disk. The location is always track (cylinder) 0, side (head) 0, and sector 1.
The Master Boot Record contains the Partition Table for the disk and a small amount of executable code. On x86-based computers, the executable code examines the Partition Table, and identifies the system partition. The Master Boot Record then finds the system partition's starting location on the disk, and loads an copy of its Partition Boot Sector into memory. The Master Boot Record then transfers execution to executable code in the Partition Boot Sector.
Note: Although there is a Master Boot Record on every hard disk, the executable code in the sector is used only if the disk is connected to an x86-based computer and the disk contains the system partition.
The example below shows a hex dump of the sector containing the Master Boot Record. The figure shows the sector in two parts:
Physical Sector:Cyl 0,Side 0,Sector 1
00000000:00 33 C0 8E D0 BC 00 7C -8B F4 50 07 50 1F FB FC .3.....|..P.P..
00000010:BF 00 06 B9 00 01 F2 A5 -EA 1D 06 00 00 BE BE 07 ................
00000020:B3 04 80 3C 80 74 0E 80 -3C 00 75 1C 83 C6 10 FE ...<.t..<.u.....
00000030:CB 75 EF CD 18 8B 14 8B -4C 02 8B EE 83 C6 10 FE .u......L.......
00000040:CB 74 1A 80 3C 00 74 F4 -BE 8B 06 AC 3C 00 74 0B .t..<.t.....<.t.
00000050:56 BB 07 00 B4 0E CD 10 -5E EB F0 EB FE BF 05 00 V.......^.......
00000060:BB 00 7C B8 01 02 57 CD -13 5F 73 0C 33 C0 CD 13 ..|...W.._s.3...
00000070:4F 75 ED BE A3 06 EB D3 -BE C2 06 BF FE 7D 81 3D Ou...........}.=
00000080:55 AA 75 C7 8B F5 EA 00 -7C 00 00 49 6E 76 61 6C U.u.....|..Inval
00000090:69 64 20 70 61 72 74 69 -74 69 6F 6E 20 74 61 62 id partition tab
000000A0:6C 65 00 45 72 72 6F 72 -20 6C 6F 61 64 69 6E 67 le.Error loading
000000B0:20 6F 70 65 72 61 74 69 -6E 67 20 73 79 73 74 65 operating syste
000000C0:6D 00 4D 69 73 73 69 6E -67 20 6F 70 65 72 61 74 m.Missing operat
000000D0:69 6E 67 20 73 79 73 74 -65 6D 00 00 80 45 14 15 ing system...E..
000000E0:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
000000F0:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000100:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000110:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000120:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000130:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000140:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000150:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000160:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000170:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000180:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
00000190:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
000001A0:00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 ................
000001B0:00 00 00 00 00 00 00 00 -FD 4E F2 14 00 00 .........N......
80 01 ..
000001C0:01 00 06 0F 7F 96 3F 00 -00 00 51 42 06 00 00 00 .....?...QB....
000001D0:41 97 07 0F FF 2C 90 42 -06 00 A0 3E 06 00 00 00 A....,.B...>....
000001E0:C1 2D 05 0F FF 92 30 81 -0C 00 A0 91 01 00 00 00 .-....0.........
000001F0:C1 93 01 0F FF A6 D0 12 -0E 00 C0 4E 00 00 55 AA ...........N..U.The information about primary partitions and an extended partition is contained in the Partition Table, a 64-byte data structure located in the same sector as the Master Boot Record (cylinder 0, head 0, sector 1). The Partition Table conforms to a standard layout that is independent of the operating system. Each Partition Table entry is 16 bytes long, making a maximum of four entries available. Each entry starts at a predetermined offset from the beginning of the sector, as follows:
The last two bytes in the sector are a signature word for the sector and are always 0x55AA. The next example is a printout of the Partition Table for the disk shown in an example earlier in this chapter. When there are fewer than four partitions, the remaining fields are all zeros.
80 01 .. 000001C0:01 00 06 0F 7F 96 3F 00 -00 00 51 42 06 00 00 00 .....?...QB.... 000001D0:41 97 07 0F FF 2C 90 42 -06 00 A0 3E 06 00 00 00 A....,.B...>.... 000001E0:C1 2D 05 0F FF 92 30 81 -0C 00 A0 91 01 00 00 00 .-....0......... 000001F0:C1 93 01 0F FF A6 D0 12 -0E 00 C0 4E 00 00 55 AA ...........N..U.
The following table describes each entry in the Partition Table. The sample values correspond to the information for partition 1.
Partition Table Fields
Byte Offset | Field Length | Sample Value | Meaning |
|---|---|---|---|
00 | BYTE | 0x80 | Boot Indicator. Indicates whether the partition is the system partition. Legal values are: |
01 | BYTE | 0x01 | |
02 | 6 bits | 0x01 | Starting Sector. Only bits 0-5 are used. Bits 6-7 are the upper two bits for the Starting Cylinder field. |
03 | 10 bits | 0x00 | Starting Cylinder. This field contains the lower 8 bits of the cylinder value. Starting cylinder is thus a 10-bit number, with a maximum value of 1023. |
04 | BYTE | 0x06 | System ID. This byte defines the volume type. In Windows NT, it also indicates that a partition is part of a volume that requires the use of the HKEY_LOCAL_MACHINE\SYSTEM\DISK Registry subkey. |
05 | BYTE | 0x0F | |
06 | 6 bits | 0x3F | Ending Sector. Only bits 0-5 are used. Bits 6-7 are the upper two bits for the Ending Cylinder field. |
07 | 10 bits | 0x196 | Ending Cylinder. This field contains the lower 8 bits of the cylinder value. Ending cylinder is thus a 10-bit number, with a maximum value of 1023. |
08 | DWORD | 3F 00 00 00 | |
12 | DWORD | 51 42 06 00 |
The remainder of this section describes the uses of these fields. Definitions of the fields in the Partition Table is the same for primary partitions, extended partitions, and logical drives in extended partitions.
The Boot Indicator field indicates whether the volume is the system partition. On x-86-based computers, only one primary partition on the disk should have this field set. This field is used only on x86-based computers. On RISC-based computers, the NVRAM contains the information for finding the files to load.
On x86-based computers, it is possible to have different operating systems and different file systems on different volumes. For example, a computer could have MS-DOS on the first primary partition and Windows 95, UNIX, OS/2, or Windows NT on the second. You control which primary partition (active partition in FDISK) to use to start the computer by setting the Boot Indicator field for that partition in the Partition Table.
For primary partitions and logical drives, the System ID field describes the file system used to format the volume. Windows NT uses this field to determine what file system device drivers to load during startup. It also identifies the extended partition, if there is one defined.
These are the values for the System ID field:
Table 3-1 System ID Field Values
Value | Meaning |
|---|---|
0x01 | 12-bit FAT primary partition or logical drive. The number of sectors in the volume is fewer than 32680. |
0x04 | 16-bit FAT primary partition or logical drive. The number of sectors is between 32680 and 65535. |
0x05 | Extended partition. See section titled "Logical Drives and Extended Partitions," presented later in this chapter, for more information. |
0x06 | BIGDOS FAT primary partition or logical drive. |
0x07 | NTFS primary partition or logical drive. |
Figure presented earlier in this section, has examples of a BIGDOS FAT partition, an NTFS partition, an extended partition, and a 12-bit FAT partition.
If you install Windows NT on a computer that has Windows 95 preinstalled, the FAT partitions might be shown as unknown. If you want to be able to use these partitions when running Windows NT, your only option is to delete the partitions.
OEM versions of Windows 95 support the following four partition types for FAT file systems that Windows NT cannot recognize.
Table 3-2 Partition Types
Value | Meaning |
|---|---|
0x0B | Primary Fat32 partition, using interrupt 13 (INT 13) extensions. |
0x0C | Extended Fat32 partition, using INT 13 extensions. |
0x0E | Extended Fat16 partition, using INT 13 extensions. |
0x0F | Primary Fat16 partition, using INT 13 extensions. |
When you create a volume set or a stripe set, Disk Administrator sets the high bit of the System ID field for each primary partition or logical drive that is a member of the volume. For example, a FAT primary partition or logical drive that is a member of a volume set or a stripe set has a System ID value of 0x86. An NTFS primary partition or logical drive has a System ID value of 0x87. This bit indicates that Windows NT needs to use the HKEY_LOCAL_MACHINE\SYSTEM\DISK Registry subkey to determine how the members of the volume set or stripe set relate to each other. Volumes that have the high bit set can only be accessed by Windows NT.
When a primary partition or logical drive that is a member of a volume set or a stripe set has failed due to write errors or cannot be accessed, the second most significant bit is set. The System ID byte is set to C6 in the case of a FAT volume, or C7 in the case of an NTFS volume.
Note
If you start up MS-DOS, it can only access primary partitions or logical drives that have a value of 0x01, 0x04, 0x05, or 0x06 for the System ID. However, you should be able to delete volumes that have the other values. If you use a MS-DOS-based low-level disk editor, you can read and write any sector, including ones that are in NTFS volumes.
On Windows NT Server, mirror sets and stripe sets with parity also require the use of the Registry subkey HKEY_LOCAL_MACHINE\SYSTEM\DISK to determine how to access the disks.
深入浅出硬盘分区表
php中Cookie及其使用
Cookie技术是一个非常有争议的技术,自经诞生它就成了广大网络用户和Web开发人员的
一个争论焦点。有一些网络用户,甚至包括一些资深的Web专家也对它的产生和推广感到不满,这倒不是因为
Cookie技术的功能太弱或别的技术性能上的原因,而仅仅是因为他们觉得Cookie 的使用,对网络用户的隐私
构成了危害。因为Cookie是由Web服务器保存在用户浏览器上的小文本文件,它包含有关用户的信息(如身份
识别号码、密码、用户在Web站点上购物的方式或用户访问该站点的次数)。
那么Cookie 技术究竟怎样呢?是否真的给网络用户带来了个人隐私的危害呢?还是让我们看了下面的内
容,再做回答吧。
(1)Cookie技术简介
在WEB技术发展史上,Cookie技术的出现是一个重大的变革。最先是Netscape在它的Netscape Navigator
浏览器中引入了Cookie技术,从那时起,World Wide Web 协会就开始支持Cookie标准。以后又经过微软的大
力推广(因为微软的IIS Web服务器所采用的ASP技术很大程度的使用了Cookie技术),即在微软的Internet
Explorer浏览器中完全支持Cookie技术。到现在,绝大多数的浏览器都支持Cookie技术,或者至少兼容Cookie
技术的使用。
1)什么是Cookie?
按照Netscape官方文档中的定义,Cookie是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的
一种方式。Cookie 是由Web服务器保存在用户浏览器上的小文本文件,它可以包含有关用户的信息(如身份
识别号码、密码、用户在Web站点购物的方式或用户访问该站点的次数)。无论何时用户链接到服务器,Web
站点都可以访问Cookie信息。
通俗地讲,浏览器用一个或多个限定的文件来支持Cookie。这些文件在使用Windows操作系统的机器上叫
做Cookie 文件,在Macintosh机器上叫做magic Cookie 文件,这些文件被网站用来在上面存储Cookie数据。
网站可以在这些Cookie 文件中插入信息,这样对有些网络用户就有些副作用。有些用户认为这造成了对个人
隐私的侵犯,更糟的是,有些人认为Cookie是对个人空间的侵占,而且会对用户的计算机带来安全性的危害。
目前有些Cookie 是临时的,另一些则是持续的。临时的Cookie只在浏览器上保存一段规定的时间,一旦
超过规定的时间该Cookie就会被系统清除。例如在PHP中Cookie被用来跟踪用户进程直到用户离开网站。持续
的Cookie则保存在用户的Cookie文件中,下一次用户返回时,仍然可以对它进行调用。
在Cookie文件中保存Cookie,一些用户会过分地认为这将带来很大的问题。主要是有些用户担心Cookie
会跟踪用户网上冲浪的习惯,譬如用户喜爱到那些类型的站点、爱从事些什么活动等。害怕这种个人信息一
旦落入一些别有用心的家伙手中,那么个人也就可能成为一大堆广告垃圾的对象,甚至遭到意外的损害。不
过,这种担心压根儿不会发生,因为网站以外的用户是无法跨过网站来获得Cookie信息的。所以想以这种目
的来应用Cookie是不可能的。不过,由于一些用户错误的理解以及“以讹传讹”,一些浏览器开发商别无选
择,只好作出相识的响应(例如Netscape Navigator4.0和Internet Explorer3.0都提供了屏蔽Cookie 的选
项)。
对Cookie技术期待了这么久的结果是,迫使许多浏览器开发商在它们的浏览器中提供了对Cookie的灵活
性控制功能。例如,目前的两大主流浏览器Netscape Navigator 和 Internet Explorer是这样处理Cookie
的:Netscape Navigator4.0不但可以接受Cookie进行警告,而且还可以屏蔽掉Cookie;InternetExplorer3.0
也可以屏蔽Cookie,但在Internet Explorer4.0中就只能进行接受警告而没有提供屏蔽选项,不过在Internet
Explorer4.0之后的更新版本中又加入了屏蔽Cookie的功能选项。
此外,很多最新的技术甚至已经可以在不能屏蔽Cookie的浏览器上进行Cookie的屏蔽了。例如,可以通
过将Cookie文件设置成不同的类型来限制Cookie的使用。但是,非常不幸地是,要是你想完全屏蔽Cookie的
话,肯定会因此拒绝许多的站点页面。因为当今已经有许多Web站点开发人员爱上了Cookie技术的强大功能,
例如Session对象的使用就离不开Cookie的支持。
尽管今天仍有一些网络用户对于Cookie的争论乐此不倦,但是对于绝大多数的网络用户来说还是倾向于
接受Cookie的。因此,我们尽可以放心地使用Cookie技术来开发我们的WEB页面。
2)Cookie是怎样工作的?
要了解Cookie,必不可少地要知道它的工作原理。一般来说,Cookie通过HTTP Headers从服务器端返回
到浏览器上。首先,服务器端在响应中利用Set-Cookie header来创建一个Cookie ,然后,浏览器在它的请
求中通过Cookie header包含这个已经创建的Cookie,并且反它返回至服务器,从而完成浏览器的论证。
例如,我们创建了一个名字为login的Cookie来包含访问者的信息,创建Cookie时,服务器端的Header
如下面所示,这里假设访问者的注册名是“Michael Jordan”,同时还对所创建的Cookie的属性如path、
domain、expires等进行了指定。
Set-Cookie:login=Michael Jordan;path=/;domain=msn.com;
expires=Monday,01-Mar-99 00:00:01 GMT
上面这个Header会自动在浏览器端计算机的Cookie文件中添加一条记录。浏览器将变量名为“login”
的Cookie赋值为“Michael Jordon”。注意,在实际传递过程中这个Cookie的值是经过了URLEncode方法的
URL编码操作的。 这个含有Cookie值的HTTP Header被保存到浏览器的Cookie文件后,Header就通知浏览器
将Cookie通过请求以忽略路径的方式返回到服务器,完成浏览器的认证操作。
此外,我们使用了Cookie的一些属性来限定该Cookie的使用。例如Domain属性能够在浏览器端对Cookie
发送进行限定,具体到上面的例子,该Cookie只能传达室到指定的服务器上,而决不会跑到其他的如
www.hp.com的Web站点上去。Expires属性则指定了该Cookie保存的时间期限,例如上面的Cookie在浏览器上
只保存到1999年3月1日1秒。当然,如果浏览器上Cookie 太多,超过了系统所允许的范围,浏览器将自动对
它进行删除。至于属性Path,用来指定Cookie将被发送到服务器的哪一个目录路径下。
说明:浏览器创建了一个Cookie后,对于每一个针对该网站的请求,都会在Header中带着这个Cookie;
不过,对于其他网站的请求Cookie是绝对不会跟着发送的。而且浏览器会这样一直发送,直到Cookie过期为止。
上一部分讲了有关Cookie的技术背景,这部分来说说在PHP里如何设置、使用、删除Cookie,及Cookie
的一些限制。PHP对Cookie支持是透明的,用起来非常方便。
1、设置Cookie
PHP用SetCookie函数来设置Cookie。必须注意的一点是:Cookie是HTTP协议头的一部分,用于浏览器和
服务器之间传递信息,所以必须在任何属于HTML文件本身的内容输出之前调用Cookie函数。SetCookie 函数
定义了一个Cookie,并且把它附加在HTTP头的后面,SetCookie函数的原型如下:
int SetCookie(string name, string value, int expire, string path,
string domain, int secure);
除了name之外所有的参数都是可选的。value,path,domain 三个参数可以用空字符串代换,表示没有设
置;expire和 secure两个参数是数值型的,可以用0表示。expire参数是一个标准的Unix时间标记,可以用
time()或mktime() 函数取得,以秒为单位。secure参数表示这个Cookie是否通过加密的HTTPS协议在网络上
传输。
当前设置的Cookie 不是立即生效的,而是要等到下一个页面时才能看到.这是由于在设置的这个页面里
Cookie由服务器传递给客户浏览器,在下一个页面浏览器才能把Cookie从客户的机器里取出传回服务器的原
因。在同一个页面设置Cookie,实际是从后往前,所以如果要在插入一个新的Cookie之前删掉一个,你必须
先写插入的语句,再写删除的语句,否则可能会出现不希望的结果。
来看几个例子:
简单的:
SetCookie("MyCookie", "Value of MyCookie");
带失效时间的:
SetCookie("WithExpire", "Expire in 1 hour", time()+3600);//3600秒=1小时
什么都有的:
SetCookie("FullCookie", "Full cookie value", time()+3600, "/forum", ".phpuser.com", 1);
这里还有一点要说明的,比如你的站点有几个不同的目录,那么如果只用不带路径的Cookie的话,在一
个目录下的页面里设的Cookie在另一个目录的页面里是看不到的,也就是说,Cookie是面向路径的。实际上,
即使没有指定路径,WEB 服务器会自动传递当前的路径给浏览器的,指定路径会强制服务器使用设置的路径。
解决这个问题的办法是在调用SetCookie时加上路径和域名,域名的格式可以是“www.phpuser.com”,也可
是“.phpuser.com”。
SetCookie函数里表示value的部分,在传递时会自动被encode,也就是说,如果value的值是“test
value”在传递时就变成了“test%20value”,跟URL的方法一样。当然,对于程序来说这是透明的,因为在
PHP接收Cookie的值时会自动将其decode。
如果要设置同名的多个Cookie,要用数组,方法是:
SetCookie("CookieArray[]", "Value 1");
SetCookie("CookieArray[]", "Value 2");
或
SetCookie("CookieArray[0]", "Value 1");
SetCookie("CookieArray[1]", "Value 2");
2、接收和处理Cookie
PHP对Cookie的接收和处理的支持非常好,是完全自动的,跟FORM变量的原则一样,特别简单。比如设
置一个名为MyCookier的Cookie,PHP会自动从WEB服务器接收的HTTP头里把它分析出来,并形成一个与普通
变量一样的变量,名为$myCookie,这个变量的值就是Cookie的值。数组同样适用。另外一个办法是引用PHP
的全局变量$HTTP_COOKIE_VARS数组。
分别举例如下:(假设这些都在以前的页面里设置过了,并且仍然有效)
echo $MyCookie;
echo $CookieArray[0];
echo count($CookieArray);
echo $HTTP_COOKIE_VARS["MyCookie"];
就这么简单。
3、删除Cookie
要删除一个已经存在的Cookie,有两个办法:
一是调用只带有name参数的SetCookie,那么名为这个name的Cookie 将被从关系户机上删掉;另一个办
法是设置Cookie的失效时间为time()或time()-1,那么这个Cookie在这个页面的浏览完之后就被删除了(其
实是失效了)。
要注意的是,当一个Cookie被删除时,它的值在当前页在仍然有效的。
4、使用Cookie的限制
首先是必须在HTML文件的内容输出之前设置;
其次不同的浏览器对Cookie的处理不一致,且有时会出现错误的结果。比如:MS IE+SERVICE PACK 1
不能正确处理带域名和路径的Cookie ,Netscape Communicator 4.05和MS IE 3.0不能正确处理不带路径和
时间的Cookie。至于MS IE 5 好象不能处理带域名、路径和时间的Cookie。这是我在设计本站的页面时发现
的。
第三个限制是在客户端的。一个浏览器能创建的Cookie数量最多为30个,并且每个不能超过4KB,每个WEB
站点能设置的Cookie总数不能超过20个。
关于Cookie的话题,就说到这儿了。
(由于Cookie最初由Netscape定义的,所以附上Netscape公司关于Cookie的官方原始定义的网址:
_spec.html" target=_blank>http://www.netscape.com/newsref
/std/cookie_spec.html)
Cookie技术是一个非常有争议的技术,自经诞生它就成了广大网络用户和Web开发人员的
一个争论焦点。有一些网络用户,甚至包括一些资深的Web专家也对它的产生和推广感到不满,这倒不是因为
Cookie技术的功能太弱或别的技术性能上的原因,而仅仅是因为他们觉得Cookie 的使用,对网络用户的隐私
构成了危害。因为Cookie是由Web服务器保存在用户浏览器上的小文本文件,它包含有关用户的信息(如身份
识别号码、密码、用户在Web站点上购物的方式或用户访问该站点的次数)。
css定位(position)属性
css对各浏览器的兼容问题
CSS浏览器兼容问题
