• linux基础知识-14


    一个有趣的逻辑,把一个文件保存在两个地方,但只有一份, 或者说用两个不同的文件名保存一个文件,这种思想有些反人类,但这就是linux下的硬链接。

    下面是见证奇迹的时刻,老陌认真的做了这个例子,一来是巩固一下之前学习的知识,二来体验一下硬链接。


    故事是这样的……

    某天一个帅哥(kevin),一个美女(alice)来找老陌,他们要共同编写一本小说,想让老陌在服务器上创建两个账号,他们谁有空闲时间就登录服务器进行编写。由于是共同合作编写,所以他们不想每写一点就通过email传来传去,之后拼接整理,很麻烦。 能不能有一种方法两个人在各自的目录里编写,但对方打开自己的文件之后却是更新的。

    挺晕,因为老陌头一次接触,所以换个说法:

    kevin在自己的家目录里创建了story目录,里面有一个小说叫九阳神帝。 这一天kevin心血来潮写下了一段,之后没词了,保存之后出去渡假了。

    alice也在自己的家目录里创建了story目录,因为和kevin共同编写,所以alice的story目录里的小说也叫九阳神帝。在kevin渡假其间alice打开九阳神帝,发现开头已经写好了,于是继续写。

    这一天alice打小怪兽去了,正好kevin回来,打开九阳神帝发现alice已经写好多了。于是kevin继续写……

    现在老陌懂了,在不同目录里的两个文件,好像同一个文件一样,其中一人修改,另一端也发生变化。当然,这个思维很无聊,不要上纲上线,就是为了说明硬连接的问题。

    在alice和kevin的不断请求下,老陌答应了。

    一、硬连接

    老陌分析了一下需求,首先要添加两个用户,这还不简单,打开控制中心……
    NO! No! 这样逼格太低了,怎么也得让老陌在帅哥,美女面前炫耀一翻。

    (一)创建用户

    #创建用户
    sudo useradd -m  -s /bin/bash kevin
    sudo useradd -m  -s /bin/bash alice
    
    #设置密码
    sudo passwd kevin
    sudo passwd alice
    

    (二)创建组

    因为两个不同的用户要共同访问同一个文件,根据前面学习的知识,应该在组或其它人的权限上下手。由于他们二人共同合作,不想让第三方人来破坏,所以老陌选择用共同组的方式来管理文件。

    ##创建组
    sudo groupadd story
    
    ##把alice, kevin添加到组中
    sudo usermod -a -G story kevin
    sudo usermod -a -G story alice
    

    (三)构建结构

    kevin,alice各自登录构建自己的目录结构。

    1. kevin构建结构

    #切换用户
    su - kevin
    
    #创建目录
    mkdir story
    
    #修改story目录的组所有者为:story组,并设置组所有者的权限为:rwx
    chgrp story story
    chmod g=rwx story
    
    #创建小说,修改小说的组所有者为story,并设置组所有者的权限为:rw-
    touch story/九阳神帝
    chgrp story story/九阳神帝
    chmod g=rw- story/九阳神帝
    

    2. alice构建结构

    #切换用户
    su - alice
    
    #创建目录
    mkdir story
    
    #修改story目录的组所有者为:story组,并设置组所有者的权限为:rwx
    chgrp story story
    chmod g=rwx story
    

    (四)创建硬连接

    目前alice并没有创建九阳神帝这个文件,因为需要把kevin的九阳神帝文件硬连接到alice的story目录中,硬连接之后表示这两个文件是同一个文件。

    ln story/九阳神帝 /home/alice/story/九阳神帝
    

    ln命令是创建链接的命令,比如快捷方式(软链接)就是通过这个命令创建的。类似于cp命令,把一个文件复制到另一个地方,但ln是在另一个地方创建的链接,而不是文件的副本。

    (五)测试

    这一天kevin心血来潮写下了一段,之后没词了,保存之后出去渡假了。

    一阵剧痛,老陌醒来发现这是一个陌生的地方……
    看看自己的双手满是鲜血,衣服和之前也不一样,莫非穿越了?

    在kevin渡假其间alice打开九阳神帝,发现开头已经写好了,于是继续写……

    见证奇迹的时刻来了:

    alice登录之后发现九阳神帝中已经有写好的内容了。

    二、硬链接详述

    当kevin创建/home/kevin/story/九阳神帝时,就包括了一个dentry,inode,data,当用ln命令创建一个硬连接后,该文件还是只有一个inode和data,但有两个dentry与之相连。

    结构如下:

    可以看出一个文件两个文件名。 此时用ls -l查看一下:

    linux@ccloves:~$ ls -l /home/alice/story/九阳神帝  
    -rw-rw-r-- 2 kevin story 152 7月  17 08:35 /home/alice/story/九阳神帝
    

    我们发现链接数是2,如果修改文件权限呢?看看另一端是不是发生变化:

    首先查看两个文件的权限相同,之后给其他人一个w权限,再查看发现另一端也变化了,因为他们是同一个inode。

    如果删除该文件是什么效果呢?

    alice@ccloves:~/story$ rm 九阳神帝 
    alice@ccloves:~/story$ ls /home/kevin/story/
    九阳神帝
    

    alice删除了自己的九阳神帝,但我们发现kevin目录中的九阳神帝还存在。再查看一下链接点:

    -rw-rw-rw- 1 kevin story 152 7月  17 08:35 九阳神帝
    

    发现刚才是2,现在变成1了,可以看出rm删除文件时,并不是把数据清空,而是脱链,当inode连接数是0了,表示这个文件被删除了。

    三、软链接

    软链接就是一个快捷方式,有windows经验的人都能理解。软链接本身是一个文件,但这个文件不存放数据,存放一个链接,指向其它文件。

    创建的方法和硬链接类似:

    发现就是多了一个选项 -s 表示这是软链接。

    通过 ls-l 我们发现软链接的文件类型是l,这说明软链接不是一个常规文件,而是一个符号链接文件。符号链接文件有自己的dentry,有自己的inode,但data域中存放的是另一个文件名,从而实现了链接。当linux访问符号链接文件时会自动解析目标文件。

    注意事项

    软链接有几个硬连接不会出现的问题:

    • 空链接:目标丢失,连接失效。
    • 递归链接:即a -> b, b -> a

    我们发现linux在尝试多层后,认为这是递归链接,警告退出。

    四、软硬链接比较

    硬链接 软链接
    目录之间不能用硬链接 软链接可以关联到目录
    硬链接没有原始和复制的概念 软链接有引用和被引用的概念,删除目标则成为空链接
    硬链接必须在同一个分区内 软链接可以在不同的分区进行链接
    chroot的目录间可共享硬链接 软链接不能引用chroot目录外的文件

    对于chroot这点老陌不懂,没有见过,先记下,等以后学到chroot再研究。

    五、目录结构

    上面我们了解文件由dentry,inode,data组成,dentry关联到inode, inode关联到data。 那目录的结构是什么呢?

    目录也是文件,所以他们结构是一样的,dentry,inode,data,只不过data中保存的是与目录相关联的dentry。老陌理解的是文件data中包含数据,比如:文本, 目录data区包含文件和目录,就这点区别。

    一个文件一般有一个链接,因为就一个dentry,之前的硬链接有两个dentry,所以链接数是2。 但我们观察目录的链接数总是大于等于2,这是为什么?

    我们通过ls -ld book查看book目录,发现链接数是4,是哪些dentry链接到这个inode上了呢?查看一下:

    [linux@ccloves test]$ ls -la book
    总用量 16
    drwxr-xr-x 4 linux linux 4096 7月  17 15:45 .
    drwxr-xr-x 3 linux linux 4096 7月  17 15:45 ..
    -rw-r--r-- 1 linux linux    0 7月  17 15:45 价格表.txt
    drwxr-xr-x 2 linux linux 4096 7月  17 15:45 三国演义
    drwxr-xr-x 2 linux linux 4096 7月  17 15:45 西游记
    

    这里老陌加了一个参数-a,发现里面多了.和..这两个目录,所以:

    • 目录本身,即"." 是一个dentry。
    • 父目录 ".." 会包含目录项book,也就是说在父目录里会引用这个book, 即又一个dentry链接到这个inode上了。
    • 子目录三国演义中有".."指向了book,又被链接了一次。
    • 子目录西游记中有".."指向了book

    通过观察被引用了4次,所以链接数是4。

    总结一下:

    目录就是包含一些目录项,目录项建立文件名与i-节点的映射,每个目录都包含至少两个引用,"."指向自身和父目录的目录项引用,另外的引用由目录下子目录的".."构成。

    六、设备节点

    之前我们学习了三种文件:普通文件,目录,符号链接。
    文件系统中存在的设备节点与普通文件,目录和符号链接包含数据的方式不同,它就像一个通往内核设备驱动的管道,当向设备节点写入数据时,它将数据传递给适当的内核设备驱动。读数据时,从相应的设备节点读取数据,就像直接从设备上读取数据一样。
    老陌理解这是高度抽象,把硬件看成文件了,读写都一个模式,只是内部工作方式不同。

    (一) 块设备和字符设备

    这些设备文件存放在/dev的专用目录里面。用ls查看发现:

    brw-rw----  1 root disk        8,  18 7月  17 10:21 sdb2
    brw-rw----  1 root disk        8,  21 7月  17 10:21 sdb5
    brw-rw----  1 root disk        8,  22 7月  17 10:21 sdb6
    crw-rw----  1 root disk       21,   0 7月  17 10:21 sg0
    

    开头是b的是块设备文件,开头是c的是字符设备文件。

    • 字符设备是按字节流读写的设备。如键盘,鼠标,声卡,打印机。
    • 块设备读写一次会读写一大块数据,允许随机访问,即从设备的任意位置读取。典型的块设备如:硬盘,软驱,光驱等。

    (二) 终端设备

    之前学习过tty1,tty2这些是终端,它们的名字与设备节点进行关联,就像sda关联到第一块硬盘一样。 这些终端也是以文件的形式存放在/dev/目录下。

    下面我们向终端设备写数据测试一下,首先ctrl+alt+f1登录到终端,之后ctrl+alt+f2用相同的用户登录到终端,再切回到tty1,之后执行命令看看效果:

    echo "hello /dev/tty2" > /dev/tty2
    

    通过重定向的方式,把数据写到/dev/tty2中。

    我们看到 “hello /dev/tty2” 已经在tty2终端显示了。

    (三)设备权限

    我们这次把数据写到/dev/tty3设备节点上:

    echo "hello" > /dev/tty3
    -bash: /dev/tty3: Permission denied
    

    此时会发现权限拒绝,因为kevin用户并没有登录到/dev/tty3终端,因此他并不拥有该设备使用权。

    我们查看一下设备文件发现,kevin登录之后/dev/tty1,/dev/tty2的文件所有者就变成了kevin,而未登录的用户所有者是root

    root@localhost ~]# ls -l /dev/tty[1-6]
    crw--w----. 1 kevin tty 4, 1 7月  17 06:30 /dev/tty1
    crw--w----. 1 kevin tty 4, 2 7月  17 06:27 /dev/tty2
    crw--w----. 1 root  tty 4, 3 7月  17 06:30 /dev/tty3
    

    我们把设备节点看成文件(硬件抽象成文件),既然是文件就有用户所有者,组所有者和权限,对设备节点的读写操作权限同普通文件一样。

    好了,以上知识点我们只作为了解。

  • 相关阅读:
    【血型】+【星座】准到吓人
    一落叶而知秋为什么有些树到冬天要落叶?
    WebDAV介绍
    Ruby concurrency explained
    lexus.cnblogs.com
    微博拉近了大家的距离
    High Performance Ruby Part 3: nonblocking IO and web application scalability
    Taglib确实减轻了开发负担[转]
    php中urldecode()和urlencode()起什么作用啊
    header中ContentDisposition的作用
  • 原文地址:https://www.cnblogs.com/myccloves/p/9322739.html
Copyright © 2020-2023  润新知