Hard links and Soft links详解

发表于:2007-07-04来源:作者:点击数: 标签:
索引节点、硬连接和连接计数 http://lists.virus.org/bugtraq-0311/msg00279.html 符号链接 http://linuxgazette.net/105/pitcher.html Hard links and Soft links 索引节点、硬连接和连接计数 索引节点inode: 引用: Linux 为每个文件分配一个称为索引节点

索引节点、硬连接和连接计数 http://lists.virus.org/bugtraq-0311/msg00279.html
符号链接                                 http://linuxgazette.net/105/pitcher.html
Hard links and Soft links

索引节点、硬连接和连接计数

索引节点inode:

引用:
Linux为每个文件分配一个称为索引节点的号码inode,可以将inode简单理解成一个指针,它永远指向本文件的具体存储位置。系统是通过索引节点(而不是文件名)来定位每一个文件。


例如:

假设我们在硬盘当前目录下建立了一个名为mytext文本文件,其内容只有一行:

代码:
This is my file.


代码:
1、当然这行文字一定是存储在磁盘数据区某个具体位置里(物理上要通过磁头号、柱面号和扇区号来描述,在本例中假设分别是1、20、30)。

2、假设其inode是262457,那么系统通过一段标准程序,就能将这个inode转换成存放此文件的具体物理地址(1磁头、20柱面、30扇区),最终读出文件的内容:“This is my file.”

3、所以inode是指向一个文件数据区的指针号码,一个inode对应着系统中唯一的一片物理数据区,而位于两个不同物理数据区的文件必定分别对应着两个不同的inode号码。


文件拷贝命令与硬链接的区别:

代码:
# cp /home/zyd/mytext newfile


在当前工作目录建立了一个新文件newfile,其实际操作主要包括如下三步:

引用:
1、在当前目录中增加一个目录项,其文件名域填入newfile,并分配了一个新的inode,假设是262456。
2、将原文件(在1磁头、20柱面、30扇区)的内容复制了一份到新的空闲物理块(假设是1磁头、20柱面、31扇区)。
3、填写一些其他关键信息,使系统通过这些信息及inode号码可以完成物理地址的转换。


所以文件复制要分配新的inode和新的数据区,虽然两个文件的内容是一样的。


硬连接hardlink:

引用:
我们实际使用文件时一般是通过文件名来引用的。通过上面的讨论,我们知道:

1个inode号码肯定和一片完全属于一个文件的数据区一一对应。那么一个文件系统中两个或更多个不同的文件名能否对应同一个文件呢?答案是肯定的。

我们知道inode号码是记录在文件名对应的目录项中的,我们可以使两个或多个文件的目录项具有相同的inode值,实际上就使它们对应着同一个文件。

有几个目录项具有相同的inode号,我们就说这个文件有几个硬连接(hardlink),

对于普通文件,ls -l命令的连接计数count域的数值就是本文件拥有的硬连接数。硬连接可以通过ln命令建立,


例如:

代码:
# ln /home/zyd/mytext hardlink_mytext


就建立了一个新的文件hardlink_mytext,这个文件的inode同样是262457。建立硬连接实际上只是增加了一个目录项,但并复制文件数据区,原文件的数据区由两个文件共享。这一方面能够节约大量磁盘空间,同时可以保证两个文件能同步更新。

代码:
'ls -il'可以显示文件的inode(在下面最左边):

262456 -rw-rw-r-- 1 zyd zyd 17 Nov 3 14:52 newfile
262457 -rw-rw-r-- 2 zyd zyd 17 Nov 3 14:50 hardlink_mytext
262457 -rw-rw-r-- 2 zyd zyd 17 Nov 3 14:50 mytext



连接计数count:

前面我们介绍了,文件的连接计数域表明本系统中共有几个文件目录项的inode和本文件相同,也就是本文件共有几个硬连接。如上面的例子中hardlink_mytext和mytext文件的count值都是2。

那么对于目录,其count域的含义是什么呢?目录的count同样表示共有多少个目录项指向此目录,不过要详细说明必须进一步解释VFS文件系统的结构,为简单起见,只要这样理解就行了:(count-2)等于本目录包含的直接子目录数(就是只包括儿子,不包括孙子啦!)。

代码:
例如:如果一个目录/abc的count域为5,那么/abc目录一定包含3个子目录。



引用:
进一步说明:

硬连接文件实际上并不是一种新的文件类型,两个文件互为对方的硬连接。它们应该都是普通文件(谁能告诉我:其它类型的文件可以硬连接吗?)。两个文件除了名称或/和文件目录不同外,其它部分完全相同,更改了一个文件,另一个的文件长度、内容、更改时间等都将相应发生变化,更改了一个文件的权限位mode,另一个也会发生同样的变化。


引用:
注意连接计数字段count,互为硬连接的两个文件的count值都是2,表明有两个inode指向同一文件的inode。

当我们删除其中一个文件时,系统首先将(count-1)->count,如果结果是零,就将其目录项和数据区都删除,否则只将本目录项删除,数据区仍然保留,仍然可以通过另外的文件名访问。根据这个特性,可以通过为重要的文件建立硬连接的方法来防止其被误删除。


一个文件系统允许的inode节点数是有限的,如果文件数量太多,即使每个文件都是0字节的空文件,系统最终也会因为节点空间耗尽而不能再创建文件。所以当发现不能建立文件时首先要考虑硬盘数据区是否还有空间(可通过du命令),其次还得检查节点空间。

引用:
互为硬连接的多个文件必须位于同一个文件系统上。根设备及任何一个需要mount才能挂接进来的分区、软盘、NFS、光驱等都是一个独立的文件系统,每个文件系统有一个相应的设备号,不同文件系统中具有相同inode节 点的文件间没有任何联系。系统则通过设备号和inode号的组合唯一确定一个文件。



Linux之所以能支持多种文件系统,其实是由于Linux提供了一个虚拟文件系统VFS,VFS作为实际文件系统的上层软件,掩盖了实际文件系统底层的具体结构差异,为系统访问位于不同文件系统的文件提供了一个统一的接 口。

实际上许多文件系统并不具备inode结构,其目录结构也和以上的讨论不同,但通过VFS,系统均为其提供了虚拟一致的inode和目录项结构。

所以,'ls -il'命令实际显示的inode应该是VFS inode,也就是说,inode是存在于内存中的数据结构,而不一定是实际的硬盘结构。

但为Linux量身定做的ext2文件系统具备实际的inode和连接型目录项结构,所以,对于ext2文件系统,可以认为我们上面讨论的关于硬连接的概念是完全正确的。


符号链接

存在两种不同类型的链接,软链接和硬链接。修改其中一个,硬连接指向的是节点(inode),而软连接指向的是路径(path)



软链接文件

  软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。和win下的快捷方式差不多。链接文件甚至可以链接不存在的文件,这就产生一般称之为"断链"的问题(或曰“现象"),链接文件甚至可以循环链接自己。类似于编程语言中的递归。

命令格式:

代码:
ln [-s] source_path target_path



硬链接文件

  info ln 命令告诉您,硬链接是已存在文件的另一个名字,硬连接的命令是

代码:
ln -d existfile newfile



引用:
硬链接文件有两个限制

  1、不允许给目录创建硬链接;
  2、只有在同一文件系统中的文件之间才能创建链接。



  对硬链接文件进行读写和删除操作时候,结果和软链接相同。但如果我们删除硬链接文件的源文件,硬链接文件仍然存在,而且保留了愿有的内容。这时,系统就“忘记”了它曾经是硬链接文件。而把他当成一个普通文件。修改其中一个,与其连接的文件同时被修改

举例 说明:

代码:
$umask 022
$ cp /etc/httpd/conf/httpd.conf /usr/sam


原来前面做的试验,改变了系统默认的umask值,现在改回来为022,
举个httpd.conf文件做例 子

代码:
$ ln httpd.conf httpd1.conf
$ ln -s httpd.conf httpd2.conf



第一条为硬链接,第二条为软链接

代码:
$ ls -li


代码:
总用量 80
1077669   -rw-r--r--    2 sam      adm         34890 10月 31 00:57 httpd1.conf
1077668  lrwxrwxrwx    1 sam      adm            10 10月 31 00:58 httpd2.conf -> httpd.conf
1077669  -rw-r--r--    2 sam      adm         34890 10月 31 00:57 httpd.conf



可以看到,使用ls -li,软连接只产生了10字节的快捷而已,硬连接却实实在在的的拷贝。最前面的inode硬链接和源文件是一样的,而软链接不一样,具体看一下回复这话有误,但先这么理解,具体请看下面的回复

对http1.conf进行编辑,可以发现httpd.conf也发生了一样的变化

代码:
$ rm httpd.conf



现在删除链接的源文件,来比较不同之处

代码:
$ ls -l
总用量 44
drw-r--r--    2 sam      adm          4096 10月 30 20:14 file6
-rw-r--r--    1 sam      adm         34890 10月 31 00:57 httpd1.conf
lrwxrwxrwx    1 sam      adm            10 10月 31 00:58 httpd2.conf -> httpd.conf



发现,httpd2.conf实际已经不存在了,是断链,而httpd1.conf变也了普通文件


硬连接是不会建立Inode的,他只是在文件原来的Inode link count域再增加1而已,也因此硬链接是不可以跨越文件系统的。相反都是软连接会重新建立一个Inode,当时Inode的结构跟其他的不一样,他只是一个指明源文件的字符串信息,譬如:/usr/bin/ls,然后一旦你在/usr/bin下把ls删除掉,那么软连接将变得毫无意义。而硬链接删除的时候,系统调用会检查link count的数值,如果他大于1,那么Inode不会被回收。因此文件的内容没有不会被删除



Hard links and Soft links

Links

As was mentioned in the section on file system structure, every file has a data structure (record) known as an i-node that stores information about the file, and the filename is simply used as a reference to that data structure. A link is simply a way to refer to the contents of a file. There are two types of links:

  • Hard links: a hard link is a pointer to the file's i-node. For example, suppose that we have a file a-file.txt that contains the string "The file a-file.txt":
    % cat a-file.txtThe file a-file.txt%

    Now we use the ln command to create a link to a-file.txt called b-file.txt:

    % ls./  ../  a-file.txt% ln a-file.txt b-file.txt% ls./  ../  a-file.txt  b-file.txt

    javascript:window.open(this.src);" style="CURSOR: pointer" onload="return imgzoom(this,550)">

    The two names a-file.txt and b-file.txt now refer to the same data:

    % cat b-file.txtThe file a-file.txt%

    If we modify the contents of file b-file.txt, then we also modify the contents of file a-file.txt:

    % vi b-file.txt...% cat b-file.txtThe file a-file.txt has been modified.% cat a-file.txtThe file a-file.txt has been modified.%

    and vice versa:

    % vi a-file.txt...% cat a-file.txtThe file a-file.txt has been modified again!% cat b-file.txtThe file a-file.txt has been modified again!%

  • Soft links (symbolic links): a soft link, also called symbolic link, is a file that contains the name of another file. We can then aclearcase/" target="_blank" >ccess the contents of the other file through that name. That is, a symbolic link is like a pointer to the pointer to the file's contents. For instance, supposed that in the previous example, we had used the -s option of the ln to create a soft link:
    % ln -s a-file.txt b-file.txt
    On disk, the file system would look like the following picture:

But what are the differences between the two types of links, in practice? Let us look at an example that highlights these differences. The directory currently looks like this (let us assume that a-file.txt b-file.txt are both hard links to the same file):

% ls./  ../  a-file.txt  b-file.txt

Let us first add another symbolic link using the -s option:

% ln -s a-file.txt Symbolicb-file.txt% ls -F./  ../  a-file.txt  b-file.txt  Symbolicb-file.txt@

A symbolic link, that ls -F displays with a @ symbol, has been added to the directory. Let us examine the contents of the file:

% cat Symbolicb-file.txt The file a-file.txt has been modified again!

If we change the file Symbolicb-file.txt, then the file a-file.txt is also modified.

% vi Symbolicb-file.txt...% cat Symbolicb-file.txtThe file a-file.txt has been modified a third time!% cat a-file.txtThe file a-file.txt has been modified a third time!% cat b-file.txtThe file a-file.txt has been modified a third time!%

If we remove the file a-file.txt, we can no longer access the data through the symbolic link Symbolicb-file.txt:

% ls -F./  ../  a-file.txt  b-file.txt  Symbolicb-file.txt@% rm a-file.txtrm: remove `a-file.txt'? y% ls -F./  ../  b-file.txt  Symbolicb-file.txt@% cat Symbolicb-file.txtcat: Symbolicb-file.txt: No such file or directory

The link Symbolicb-file.txt contains the name a-file.txt, and there no longer is a file with that name. On the other hand, b-file.txt has its own pointer to the contents of the file we called a-file.txt, and hence we can still use it to access the data.

% cat b-file.txtThe file a-file.txt has been modified a third time!

Although it may seem like symbolic links are not particularly useful, hard links have their drawbacks. The most significant drawback is that hard links cannot be created to link a file from one file system to another file on another file system. A Unix file structure hierarchy can consist of several different file systems (possibly on several physical disks). Each file system maintains its own information regarding the internal structure of the system and the individual files on the system. Hard links only know this system-specific information, which make hard links unable to span file systems. Soft links, on the other hand, know the name of the file, which is more general, and are able to span file systems.

For a concrete analogy, suppose that our friend Joel User is a student at both UBC and SFU. Both universities assign him a student number. If he tries to use his UBC student number at SFU, he will not meet with any success. He will also fail if he tries to use his SFU student number at UBC. But if he uses his legal name, Joel User, he will probably be successful. The student numbers are system-specific (like hard links), while his legal name spans both of the systems (like soft links).

Here is an example that demonstrates a situation where a hard link cannot be used and a symbolic link is needed. Suppose that we try to create a hard link from the current working directory to the C header stdio.h.

% ln /usr/include/stdio.h stdio.hln: creating hard link `stdio.h' to `/usr/include/stdio.h': Invalid cross-device link% 

The ln command fails because stdio.h is stored on a different file system. If we want to create a link to it, we will have to use a symbolic link:

% ln -s /usr/include/stdio.h stdio.h% ls -llrwxrwxrwx    1 a1a1 guest          20 Apr 20 11:58 stdio.h -> /usr/include/stdio.h% ls./  ../  stdio.h@% 

Now we can view the file stdio.h just as if it was located in the working directory. For example:

% cat stdio.h /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ /* * User-visible pieces of the ANSI C standard I/O package. */ #ifndef _STDIO_H #define _STDIO_H ... % 

The entire output of the cat command was not included to save space.

Note that the long listing (ls -l) of a soft link does not accurately reflect its associated permissions. To view the permissions of the file or directory that the symbolic link references, the -L options of the ls command can be used. For example:

% ln -s /usr/include/stdio.h stdio.h% ls -l stdio.hlrwxrwxrwx   1 a1a1     undergrad     20 May 10 15:13 stdio.h -> /usr/include/stdio.h% ls -l /usr/include/stdio.h-rw-r--r--   1 root     bin        11066 Jan  5  2000 /usr/include/stdio.h% ls -lL stdio.h-rw-r--r--   1 root     bin        11066 Jan  5  2000 stdio.h

Knowledge of links becomes doubly important when working as part of a software development team, and even more so when using a source code management tool such as RCS. The man page for the ln command contains more information on Unix links and the ln.