其实啊,说起计算机操作,大部分情况下就是"增删改查"这四个大字儿,文件操作也是这么回事儿。
就是改文件的时候得用点专门的编辑器,比如那个Vim。
不过Vim这东西,真心不是一两句话就能给你讲清楚的,咱们在后续的章节再好好说道说道。
现在学文件操作命令的时候,如果得改文件内容,咱们就先用个简单的方法:
比如"echo 9527>> test"命令,这条命令就能往test这个文件最后加一行"9527",这样修改文件,简单又快捷。
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
3.1 touch命令
touch这个词儿,字面意思就是触摸一下。
在文件操作里,你要是用touch命令去"摸"一个文件,如果这文件压根儿没有,系统就会给你新建一个空白的;
如果文件已经有了呢?
它就会去更新一下这个文件的时间戳信息,像是访问时间 啊、内容修改时间 啊,还有状态修改时间 啥的,都会给你更新一遍。
不过啊,这里得提醒一下,别把touch命令当成只是用来新建文件的。
你得牢记它本质上是"触摸"文件的意思。
这个命令的基本信息如下:
- 命令名称:touch
- 英文原意:change file timestamps
- 所在路径:/bin/touch
- 执行权限:所有用户
- 功能描述:修改文件的时间戳
1、命令格式
bash
[root@localhost ~]# touch [选项] 文件名或目录名
选项:
-a: 只修改文件的访问时间(Access Time)
-c: 如果文件不存在,则不建立新文件
-d: 把文件的时间改为指定的时间
-m: 只修改文件的数据修改时间(Modify Time)
在Linux系统里,每个文件都记录着三个重要的时间点:
- 访问时间
- 数据修改时间
- 状态修改时间
你可以想象一下,访问时间就是你最后一次查看文件的时间;
数据修改时间呢,就是你最后一次改动文件内容的时间;
而状态修改时间,就是你最后一次改变文件属性或者内容的时间。
这三个时间点,你可以通过stat命令一目了然。
不过说到touch命令,这个命令挺有意思的。
它可以让你手动去更改文件的访问时间或者数据修改时间,但是呢,你不能只改状态修改时间。
这是为啥呢?
你想啊,无论你是改了访问时间还是数据修改时间,对文件来说,它的"状态"其实都发生了变化,所以状态修改时间自然就会跟着变。
这就像是你去摸了一下文件,虽然内容没变,但这个"摸"的动作本身,就改变了文件的"状态"。
注意:在Linux中,文件没有创建时间
2、常见用法
shell
[root@node01 ~]#touch cxykk.com
#建立名为cxykk.com的空文件
如果文件不存在,则会建立文件。
shell
[root@node01 ~]#touch cxykk.com
[root@node01 ~]#touch cxykk.com
#而如果文件已经存在,则也不会报错,只是会修改文件的访问时间
3.2 stat命令
在Linux系统里,文件会记录三个关键的时间:访问时间 、数据修改时间 ,还有状态修改时间 。
不过啊,奇怪的是,它并不记录文件的创建时间。要想查看文件的这些信息,包括这三个时间点,stat命令可是个得力助手,一下子就能给你展示得清清楚楚。
其基本信息如下:
- 命令名称:stat
- 英文原意:display file or file system status
- 所在路径:/usr/bin/stat
- 执行权限:所有用户
- 功能描述:显示文件或文件系统的详细信息
1、命令格式
shell
[root@node01 ~]# stat [选项] 文件名或目录名
选项:
-f: 查看文件所在的文件系统信息,而不是查看文件的信息
2、常见用法
例子1:查看文件的详细信息
shell
[root@node01 ~]# ls
anaconda-ks.cfg etc install.sh local src test usr
[root@node01 ~]# stat anaconda-ks.cfg
#文件名
File: 'anaconda-ks.cfg'
#文件大小 #占用的block大小 #块大小 #文件类型
Size: 1217 Blocks: 8 IO Block: 4096 regular file
#节点号 #链接数
Device: fd00h/64768d Inode: 67144898 Links: 1
#权限 #所有者,root
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
#访问时间
Access: 2020-03-14 16:16:43.698832249 +0800
#数据修改时间
Modify: 2020-03-14 16:16:43.702832249 +0800
#状态修改时间
Change: 2020-03-14 16:16:43.702832249 +0800
Birth: -
[root@node01 ~]#
例子2:查看文件系统信息
如果使用"-f"选项,就不再是查看指定文件的信息,而是查看这个文件所在文件系统的信息
例如:
shell
[root@node01 ~]# stat -f anaconda-ks.cfg
File: "anaconda-ks.cfg"
ID: fd0000000000 Namelen: 255 Type: xfs
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 9201265 Free: 6968831 Available: 6968831
Inodes: Total: 18411520 Free: 18255030
[root@node01 ~]#
例子3:三种时间的含义
查看系统当前时间,如下:
shell
[root@node01 ~]# date
Thu Apr 18 22:44:06 CST 2024
[root@node01 ~]#
再查看cxykk.com文件的三种时间,可以看到,和当前时间是有差别的
如下:
shell
[root@node01 ~]# stat cxykk.com
File: 'cxykk.com'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 67982437 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-04-18 22:41:58.658034989 +0800
Modify: 2024-04-18 22:41:58.658034989 +0800
Change: 2024-04-18 22:41:58.658034989 +0800
Birth: -
[root@node01 ~]#
而如果用cat命令读取一下这个文件,就会发现文件的访问时间(Access Time)变成了cat命令的执行时间
如下:
shell
[root@node01 ~]# cat cxykk.com
[root@node01 ~]# stat cxykk.com
File: 'cxykk.com'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 67982437 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-04-18 22:45:37.054327497 +0800
Modify: 2024-04-18 22:41:58.658034989 +0800
Change: 2024-04-18 22:41:58.658034989 +0800
Birth: -
当你用echo命令往文件里写点东西时,文件的数据修改时间就会相应地更新,毕竟你修改了文件内容嘛。
不过,修改了数据,系统就会觉得文件的状态也跟着变了,所以那个状态修改时间也会跟着一起改变。
简单说,你动了文件内容,系统就认为你改变了整个文件的状态。
例如:
shell
[root@node01 ~]# echo 88998> cxykk.com
-bash: 88998: Bad file descriptor
[root@node01 ~]# stat cxykk.com
File: 'cxykk.com'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 67982437 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-04-18 22:45:37.054327497 +0800
Modify: 2024-04-18 22:48:26.944757491 +0800
Change: 2024-04-18 22:48:26.944757491 +0800
Birth: -
可以看到修改时间(Modify)和状态修改时间(Change)都发生了变化
而如果只修改文件的状态(比如改变文件的所有者),而不修改文件的数据,则只会更改状态修改时间(Change Time)
如下:
shell
[root@node01 ~]# chown nobody cxykk.com
[root@node01 ~]# stat cxykk.com
File: 'cxykk.com'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 67982437 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 99/ nobody) Gid: ( 0/ root)
Access: 2024-04-18 22:45:37.054327497 +0800
Modify: 2024-04-18 22:48:26.944757491 +0800
Change: 2024-04-18 22:50:36.159330204 +0800
Birth: -
[root@node01 ~]#
可以看到只有状态修改时间(Change)发生了变化
如果你再用touch命令去"触摸"一下这个文件,那文件的三个时间可都会变哦。
这就是touch命令的特点,大家心里有个数就行啦。
例如:
shell
[root@node01 ~]# touch cxykk.com
[root@node01 ~]# stat cxykk.com
File: 'cxykk.com'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 67982437 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 99/ nobody) Gid: ( 0/ root)
Access: 2024-04-18 22:52:59.813409705 +0800
Modify: 2024-04-18 22:52:59.813409705 +0800
Change: 2024-04-18 22:52:59.813409705 +0800
Birth: -
[root@node01 ~]#
可以看到三个时间都发生了变化
3.3 cat命令
cat命令啊,就是用来查看文件内容的。
说起这个命令,还有个好玩儿的小故事呢。
想当年,带我入门的大哥跟我说,写cat命令的那哥们儿超级喜欢猫,所以就直接把这个命令命名为"猫"(cat)了。那时候的小北还挺单纯的,就信了大哥的邪。
直到有一天,小北无意间查了查cat命令的帮助,才发现原来这个命令是concatenate(就是连接、连续的意思)的缩写,跟猫儿真的是半毛钱关系都没有啊!
这个命令的基本信息如下:
- 命令名称:cat
- 英文原意:concatenate files and print on the standard output
- 所在路径:/bin/cat
- 执行权限:所有用户
- 功能描述:合并文件并打印输出到标准输出
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
1、命令格式
shell
[root@node01 ~]# cat [选项] 文件名
选项:
-A: 相当于-vET选项的整合,用于列出所有隐藏符号
-E: 列出每行结尾的回车符$
-n: 显示行号
-T: 把Tab键用^I显示出来
-v: 列出特殊字符
2、常见用法
cat命令啊,就是让你能快速地查看文件的内容。
不过,它有个特点,就是不管文件有多大,都会一下子全显示出来。
要是文件特别大的话,那你可能就只能看到最后那部分内容了,前面的就都看不到了。
虽然Linux系统里可以用"PgUp+上箭头"来向上翻页,但是这个翻页功能也是有限制的。文件如果长到一定程度,你还是看不了全部内容。
所以啊,cat命令最适合用来查看那些不太大的文件。
当然啦,Linux里还有其他方法和命令能帮你查看大文件,这个我们后面内容会说。
cat命令本身其实挺简单的,就是让你直接看到文件里面的内容。
例如:
shell
[root@node01 ~]# cat anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
# Use graphical install
...省略部分内容
而如果使用"-n"选项,则会显示行号。例如:
shell
[root@node01 ~]# cat -n anaconda-ks.cfg
1 #version=DEVEL
2 # System authorization information
3 auth --enableshadow --passalgo=sha512
4 # Use CDROM installation media
5 cdrom
6 # Use graphical install
7 graphical
...省略部分内容
如果使用"-A"选项,则相当于使用了"-vET"选项,可以查看文本中的所有隐藏符号,包括回车符($)、Tab键(^I)等。
例如:
shell
[root@node01 ~]# cat -A anaconda-ks.cfg
#version=DEVEL$
# System authorization information$
auth --enableshadow --passalgo=sha512$
# Use CDROM installation media$
cdrom$
# Use graphical install$
...省略部分内容
3.4 more命令
要是文件太大了,cat命令可能就搞不定了,这时候more命令就派上用场了。
more命令可是个分屏显示文件内容的好手,让你能一页一页地查看大文件,再也不用担心cat命令查看文件太大看不全了。
其基本信息如下:
- 命令名称:more
- 英文原意:file perusal filter for crt viewin
- 所在路径:/bin/more
- 执行权限:所有用户
- 功能描述:分屏显示文件内容
1、命令格式
shell
[root@node01 ~]# more 文件名
more命令比较简单,一般不用什么选项,命令会打开一个交互界面,可以识别一些交互命令。
常用的交互命令如下:
- 空格键:向下翻页
- b:向上翻页
- 回车键:向下滚动一行
- /字符串:搜索指定的字符串
- q:退出。
2、常见用法
shell
[root@node01 ~]# more anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
...省略部分内容
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
--More--(64%)
3.5 less命令
less命令和more命令类似,只是more是分屏显示命令,而less是分行显示命令
其基本信息如下:
- 命令名称:less
- 英文原意:opposite of more
- 所在路径:/usr/bin/less
- 执行权限:所有用户
- 功能描述:分行显示文件内容
1、命令格式
命令格式如下:
shell
[root@node01 ~]# less 文件名
2、常用用法
less命令可以使用上、下箭头,用于分行查看文件内容
shell
[root@node01 ~]# less anaconda-ks.cfg
...省略部分内容
@^minimal
@core
kexec-tools
%end
%addon com_redhat_kdump --enable --reserve-mb='auto'
%end
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
(END)
3.6 head命令
head是用来显示文件开头的命令,其基本信息如下:
- 命令名称:head
- 英文原意:output the first part of files
- 所在路径:/usr/bin/head
- 执行权限:所有用户
- 功能描述:显示文件开头的内容
1.命令格式
shell
[root@node01 ~]# head [选项] 文件名
选项:
-n 行数: 从文件头开始,显示指定行数
-v: 显示文件名
2.常见用法
shell
[root@node01 ~]# head anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
# Use graphical install
graphical
# Run the Setup Agent on first boot
firstboot --enable
# Keyboard layouts
[root@node01 ~]#
head命令默认显示文件的开头10行内容
那如果想显示指定的行数,该怎么办呢?
则只需使用"-n"选项即可,例如:
shell
[root@node01 ~]# head -n 20 anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
# Use graphical install
graphical
# Run the Setup Agent on first boot
firstboot --enable
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8
# Network information
network --bootproto=dhcp --device=ens33 --ipv6=auto --activate
network --hostname=localhost.localdomain
# Root password
rootpw --iscrypted $6$gITTGW0J23Ag6TqC$8lUE.fDdB6UTRqVmAwrTOz1tvmmy4xwU4y80OtRdfdhdBNjizSAc63yZM61bPEdMC42INMMDEmqJtSsnnPUOv.
[root@node01 ~]#
这是显示文件的开头20行内容,也可以直接写"-行数",例如:
shell
[root@node01 ~]# head -5 anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
[root@node01 ~]#
3.7 tail命令
既然有显示文件开头的命令,那就会有显示文件结尾的命令。
tail命令的基本信息如下:
- 命令名称:tail
- 英文原意:output the last part of files
- 所在路径:/usr/bin/tail
- 执行权限:所有用户
- 功能描述:显示文件结尾的内容
1.命令格式
shell
[root@node01 ~]# tail [选项] 文件名
选项:
-n 行数: 从文件结尾开始,显示指定行数
-f: 监听文件的新增内容
2.常见用法
例子1:基本用法
shell
[root@node01 ~]# tail anaconda-ks.cfg
%addon com_redhat_kdump --enable --reserve-mb='auto'
%end
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
[root@node01 ~]#
tail命令和head命令的格式基本一致,默认会显示文件的后10行
如果想显示指定的行数,则只需使用"-n"选项即可,例如:
shell
[root@node01 ~]# tail -n 5 anaconda-ks.cfg
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
[root@node01 ~]#
也可以直接写"-行数",例如:
shell
[root@node01 ~]# tail -5 anaconda-ks.cfg
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
[root@node01 ~]#
例子2:监听文件的新增内容
tail命令有一种比较有趣的用法,可以使用"-f"选项来监听文件的新增内容
例如:
shell
[root@node01 ~]# tail -f anaconda-ks.cfg
%addon com_redhat_kdump --enable --reserve-mb='auto'
%end
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
# 光标不会退出文件,而会一直监听在文件的结尾处
这条命令会显示文件的最后10行内容,而且光标不会退出命令,而会一直监听在文件的结尾处,等待显示新增内容。
这时如果向文件中追加一些数据(需要开启一个新终端),那么结果如下:
shell
Last login: Thu Apr 18 22:33:37 2024 from 192.168.25.5
[root@node01 ~]# echo test2sswwwww>> anaconda-ks.cfg
[root@node01 ~]#
可以看到原来的那个终端窗口显示出了我们刚刚增加的内容(test2sswwwww)
3.8 ln命令
想要搞明白ln命令,咱们得先说说ext文件系统是怎么运作的。
之前咱们讲过,分区格式化其实就是写入文件系统,咱们现在用的Linux系统主要采用的是ext4文件系统。
要是想用一张图来直观地展示这个ext4文件系统,如图4-1:
ext4文件系统把分区大致切成了两大部分:
一小块地方存文件的inode信息,剩下的大片地方就用来存实际的block数据。
inode的默认大小就是128字节,它记录了文件的各种属性,比如权限啊、所有者啊、文件大小啊,还有文件的各种时间戳,像是状态改变时间、最近读取时间和最近修改时间。
最厉害的是,它还存了文件数据真正保存的block编号
每个文件都得占用一个inode哦。
仔细瞅瞅,你会发现inode里其实没记录文件名,那是因为文件名是记在文件所在目录的block里的。
说到block呢,它的大小可以是1KB、2KB、4KB,系统默认是用4KB。
这个block就是用来实打实地存数据的。要是一个block装不下全部数据,那就可以多用几个block。
比如说,有个10KB的文件要存,那就得用3个block,虽然最后一个block可能没装满,但也不能往里塞别的文件数据了。
这3个block可能是连着的,也可能是分散开的
1、命令格式
了解了ext文件系统的概念,我们来看看ln命令的基本信息:
- 命令名称:ln
- 英文原意:make links between file
- 所在路径:/bin/ln
- 执行权限:所有用户
- 功能描述:在文件之间建立链接
ln命令的基本格式如下:
shell
[root@node01 ~]# ln [选项] 源文件 目标文件
选项:
-s: 建立软链接文件。如果不加"-s"选项,则建立硬链接文件
-f: 强制。如果目标文件已经存在,则删除目标文件后再建立链接文件
2、常见用法
创建硬链接:
shell
[root@node01 ~]# touch cxykk.com
#建立硬链接文件,目标文件没有写文件名,会和原名一致
#也就是/root/cxykk.com和/tmp/cxykk.com是硬链接文件
[root@node01 ~]# ln /root/cxykk.com /tmp/
创建软链接:
shell
[root@node01 ~]# touch www.cxykk.com
[root@node01 ~]# ll
total 40
-rw-------. 1 root root 1230 Apr 18 23:23 anaconda-ks.cfg
-rw-r--r-- 2 nobody root 0 Apr 21 09:16 cxykk.com
drwxr-xr-x 2 root root 6 Oct 25 22:01 etc
-rw-r--r-- 1 root root 35515 Jan 19 14:15 install.sh
drwxr-xr-x 2 root root 6 Oct 25 21:31 local
drwxr-xr-x 3 root root 18 Oct 25 21:32 src
drwxr-xr-x 2 root root 32 Apr 14 22:35 test
drwxr-xr-x 2 root root 6 Oct 25 21:31 usr
-rw-r--r-- 1 root root 0 Apr 21 09:25 www.cxykk.com
[root@node01 ~]# ln /root/www.cxykk.com /tmp/
这里需要注意的是:软链接文件的源文件必须写成绝对路径,而不能写成相对路径(硬链接没有这样的要求),否则软链接文件会报错。这是初学者非常容易犯的错误。
建立硬链接和软链接非常简单,那这两种链接有什么区别?它们都有什么作用?
这才是链接文件最不容易理解的地方,我们分别来讲讲。
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
3、硬链接作用
下面我们再来建立一个硬链接文件,然后看看这两个文件的特点:
shell
#建立源文件
[root@node01 ~]# touch ln_test
#给源文件建立硬链接文件
[root@node01 ~]# ln /root/ln_test /tmp/test_hard
[root@node01 ~]# ll -i /root/ln_test /tmp/test_hard
70382153 -rw-r--r-- 2 root root 0 Apr 21 09:40 /root/ln_test
70382153 -rw-r--r-- 2 root root 0 Apr 21 09:40 /tmp/test_hard
#查看两个文件的详细信息,可以发现这两个文件的inode号是一样的
[root@node01 ~]#
在我们之前讲inode号的时候,我们提到了每个文件都有一个独一无二的inode号,对吧?
你可以把inode号理解成是文件的身份证号。
当你要访问一个文件的内容时,系统首先得通过这个inode号来定位文件。
但有意思的是,当你创建一个硬链接时,这个硬链接和源文件的inode号居然是一模一样的。
这就让人困惑了:当我们去查找文件时,系统到底是怎么区分这两个看起来"同号"的文件的呢?
咱们画个图来更直观地理解一下,如图4-2所示:
你知道吗,在inode信息里,文件的名字是不会记录的,这玩意儿其实存储在文件所在目录的block里。
简单来说,目录的block会记录这个目录下所有子文件和子目录的名称,以及它们对应的inode号。
所以,当你真的要打开一个文件时,比如说 /root/ln_test,系统得走这几步骤:
- 首先找到根目录的inode(根目录的inode是系统已知的,inode号是2),然后判断用户是否有权限访问根目录的block
- 如果有权限,则可以在根目录的block中访问到/root/的文件名及对应的inode号
- 通过/root/目录的inode号,可以查找到/root/目录的inode信息,接着判断用户是否有权限访问/root/目录的block
- 如果有权限,则可以从/root/目录的block中读取到test文件的文件名及对应的inode号
- 通过test文件的inode号,就可以找到test文件的inode信息,接着判断用户是否有权限访问test文件的block
- 如果有权限,则可以读取block中的数据,这样就完成了/root/test文件的读取与访问。
按照这个步骤,你在 /root/ln_test 这个文件上建了一个硬链接,叫 /tmp/test_hard 。这时候,在 /root/ 和 /tmp/ 目录的block中就会分别记录 ln_test 和 test_hard 的信息,包括它们的文件名和对应的inode号。
但有意思的是,你会发现 ln_test 和 test_hard 这俩文件的inode号竟然是一模一样的,都是70382152 。这就意味着,不管你访问哪一个文件,系统实际上都是去访问那个inode号为70382152 的文件数据。
这就是硬链接的玄机所在,挺有意思的对吧?
硬链接特点如下:
- 不论是修改源文件(test文件),还是修改硬链接文件(test-hard文件),另一个文件中的数据都会发生改变
- 不论是删除源文件,还是删除硬链接文件,只要还有一个文件存在,这个文件(inode号是262147的文件)都可以被访问
- 硬链接不会建立新的inode信息,也不会更改inode的总数
- 硬链接不能跨文件系统(分区)建立,因为在不同的文件系统中,inode号是重新计算的
- 硬链接不能链接目录,因为如果给目录建立硬链接,那么不仅目录本身需要重新建立,目录下所有的子文件,包括子目录中的所有子文件都需要建立硬链接,这对当前的Linux来讲过于复杂。
需要注意的是:
硬链接的限制比较多,既不能跨文件系统,也不能链接目录,而且源文件和硬链接文件之间除inode号是一样的之外,没有其他明显的特征。
所以,这些特征都使得硬链接并不常用,大家有所了解就好
听的再多,都不如亲眼所见的真实,下面通过实验来验证下我们说的硬链接的几个特点:
1、验证特点1
shell
#向源文件中写入数据
[root@node01 ~]# echo this is a test >> /root/ln_test
#查看源文件内容
[root@node01 ~]# cat /root/ln_test
this is a test
#查看硬链接文件内容
[root@node01 ~]# cat /tmp/test_hard
this is a test
#可以看出源文件内容和硬链接内容都新增了this is a test文本内容
[root@node01 ~]#
2、验证特点2
shell
#删除源文件
[root@node01 ~]# rm -rf /root/ln_test
#查看硬链接文件内容,依然可以正常读取
[root@node01 ~]# cat /tmp/test_hard
this is a test
[root@node01 ~]#
3、验证特点3
shell
#建立源文件
[root@node01 ~]# touch ln_test
#给源文件建立硬链接文件
[root@node01 ~]# ln /root/ln_test /tmp/test_hard
[root@node01 ~]# ll -i /root/ln_test /tmp/test_hard
70382153 -rw-r--r-- 2 root root 0 Apr 21 09:40 /root/ln_test
70382153 -rw-r--r-- 2 root root 0 Apr 21 09:40 /tmp/test_hard
#查看两个文件的详细信息,可以发现这两个文件的inode号是一样的
[root@node01 ~]#
4、验证特点4
假设你有两个分区,分别挂载为 / 和 /data ,而 /data 分区是一个独立的文件系统。
你尝试从根文件系统中的 /home/user/ 目录创建一个文件,然后在 /data/ 目录创建一个硬链接指向该文件
4.1 创建源文件
shell
touch /home/user/source_file.txt
4.2 创建硬链接
shell
ln /home/user/source_file.txt /data/hard_link_to_source.txt
这条命令尝试在 /data 目录(一个独立的文件系统)中创建一个硬链接指向 /home/user/source_file.txt。在 Linux 中,这将会失败,并且你会看到类似以下的错误消息:
shell
ln: failed to create hard link '/data/hard_link_to_source.txt' => '/home/user/source_file.txt': Invalid cross-device link
5、验证特点5
shell
#创建一个目录
[root@node01 ~]# ln /root/hard_link /tmp/hard_link_test
#可以看出错误提示直接告诉你,不允许在目录上创建硬链接
ln: '/root/hard_link': hard link not allowed for directory
[root@node01 ~]#
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
4、软连接
软链接也称作符号链接,相比硬链接来讲,软链接就要常用多了。
我们先建立一个软链接,再来看看软链接的特点。
shell
[root@node01 ~]# touch soft_link
[root@node01 ~]# ln -s /root/soft_link /tmp/soft_link_test
[root@node01 ~]# ll -id /root/soft_link /tmp/soft_link_test
70382138 -rw-r--r-- 1 root root 0 Apr 21 10:43 /root/soft_link
34972611 lrwxrwxrwx 1 root root 15 Apr 21 10:43 /tmp/soft_link_test -> /root/soft_link
[root@node01 ~]#
这里需要注意的是:软链接的源文件必须写绝对路径,否则建立的软链接文件就会报错,无法正常使用
软链接在Linux里面挺好认的。
首先,看权限位上的那个"l",它就明明白白告诉你这是个软链接。
然后呢,文件名后面会跟个"->"和源文件的全名,就跟Windows的快捷方式似的。
软链接的好处多多,比如它能链接到目录 ,还能跨越不同的文件系统,这些硬链接做不到。
可以这么说,软链接就像是Windows里的快捷方式。
它们的主要作用也差不多,就是为了让某些不容易找到的文件或者目录更方便地被访问。
不过在Linux里,软链接还有其他的用途。
比如,管理员们有时会发现不同的系统把一些启动文件放在不同的地方,像 /etc/rc.local ,有的系统放在 /etc/ 目录里,有的放在 /etc/rc.d/ 里。
这时候,就可以用软链接搞定:不管你习惯哪个位置,链接一下,用起来都一样顺手。
如果你仔细观察,会发现软链接的inode号和源文件的并不一样。
这点和硬链接大不相同。咱们也可以画个图来看看软链接是怎么工作的
如图4-3所示:
软链接和硬链接在原理上最主要的不同在于它们怎么处理inode索引和数据块(block)。
硬链接其实挺简单的,它不会创建新的inode索引或者分配新的数据块。
直接使用原文件的inode信息和数据块,所以硬链接和源文件的inode号是完全一样的。
而软链接就不一样了,它会创建自己的inode索引和数据块。
但这个数据块里面不是存文件的实际数据,而是保存着源文件的文件名和inode号。
因此,软链接的inode号和源文件的就不一样。
这就像硬链接是把源文件的一个完全镜像放在另一个位置,而软链接更像是一个快捷方式,指向原来的文件。
这种设计使得软链接比硬链接更灵活,尤其是在跨文件系统链接或链接目录时。
下面我们来看看我们来看看访问软链接的步骤和访问硬链接的步骤有什么不同:
- 首先找到根目录的inode索引信息,然后判断用户是否有权限访问根目录的block
- 如果有权限访问根目录的block,就会在block中查找到/tmp/目录的inode号
- 接着访问/tmp/目录的inode信息,判断用户是否有权限访问/tmp/目录的block
- 如果有权限,就会在block中读取到软链接文件check-soft的inode号。因为软链接文件会真正建立自己的inode索引和block,所以软链接文件和源文件的inode号是不一样的
- 通过软链接文件的inode号,找到了check-soft文件inode信息,判断用户是否有权限访问block
- 如果有权限,就会发现check-soft文件的block中没有实际数据,仅有源文件check的inode号
- 接着通过源文件的inode号,访问到源文件check的inode信息,判断用户是否有权限访问block
- 如果有权限,就会在check文件的block中读取到真正的数据,从而完成数据访问。
通过这个过程,我们就可以总结出软链接的特点了:
软链接的特点和Windows中的快捷方式完全一致
那么软链接的特点也就很好总结了,主要特点如下:
- 不论是修改源文件(soft_link),还是修改软链接文件(soft_link_test),另一个文件中的数据都会发生改变
- 删除软链接文件,源文件不受影响,而删除源文件,软链接文件将找不到实际的数据,从而显示文件不存在
- 软链接会新建自己的inode信息和block,只是在block中不存储实际文件数据,而存储的是源文件的文件名及inode号
- 软链接可以链接目录
- 软链接可以跨分区
我们再通过实践带大家一一验证软链接的5个特点:
1、验证特点1
shell
#修改源文件内容
[root@node01 ~]# echo this is a soft link test >> /root/soft_link
#查看源文件内容
[root@node01 ~]# cat /root/soft_link
this is a soft link test
#查看源文件软链接到的文件内容
[root@node01 ~]# cat /tmp/soft_link_test
this is a soft link test
#可以看到,源文件和软链接文件的数据都发生了改变
[root@node01 ~]#
2、验证特点2
shell
#删除软链接文件
[root@node01 ~]# rm -rf /tmp/soft_link_test
#访问源文件,可以正常访问
[root@node01 ~]# cat /root/soft_link
this is a soft link test
#访问软链接文件,无法访问
[root@node01 ~]# cat /tmp/soft_link_test
cat: /tmp/soft_link_test: No such file or directory
#重新建立/root/soft_link和/tmp/soft_link_test的软链接
[root@node01 ~]# ln -s /root/soft_link /tmp/soft_link_test
#查看软链接建立信息
[root@node01 ~]# ll -id /root/soft_link /tmp/soft_link_test
70382138 -rw-r--r-- 1 root root 25 Apr 21 11:06 /root/soft_link
34972611 lrwxrwxrwx 1 root root 15 Apr 21 11:11 /tmp/soft_link_test -> /root/soft_link
#删除源文件
[root@node01 ~]# rm -rf /root/soft_link
#查看源文件,提示文件不存在
[root@node01 ~]# cat /root/soft_link
cat: /root/soft_link: No such file or directory
#查看软链接文件,也提示文件不存在
[root@node01 ~]# cat /tmp/soft_link_test
cat: /tmp/soft_link_test: No such file or directory
[root@node01 ~]#
3、验证特点3
shell
#建立/root/soft_link和/tmp/soft_link_test的软链接
[root@node01 ~]# ln -s /root/soft_link /tmp/soft_link_test
#查看软链接建立信息,可以看到两个文件的inode分别为70382138和34972611,不一样,原理参考图4.3
[root@node01 ~]# ll -id /root/soft_link /tmp/soft_link_test
70382138 -rw-r--r-- 1 root root 25 Apr 21 11:06 /root/soft_link
34972611 lrwxrwxrwx 1 root root 15 Apr 21 11:11 /tmp/soft_link_test -> /root/soft_link
4、验证特点4
shell
#创建一个soft-link目录
[root@node01 ~]# mkdir soft-link
#创建目录软链接
[root@node01 ~]# ln -s /root/soft-link /tmp/soft-link-new
#查看目录信息
[root@node01 ~]# ll -id /root/soft-link /tmp/soft-link-new
103997792 drwxr-xr-x 2 root root 6 Apr 21 11:17 /root/soft-link
34972615 lrwxrwxrwx 1 root root 15 Apr 21 11:18 /tmp/soft-link-new -> /root/soft-link
[root@node01 ~]#
5、验证特点5
假设你有两个分区:
/dev/sda1 挂载在 / 上,使用 ext4 文件系统
/dev/sdb1 挂载在 /data 上,使用 xfs 文件系统
你想在 /data 分区中创建一个指向 /home/user/document.txt 的软链接
- 确保源文件存在:
- 首先,确保源文件 /home/user/document.txt 确实存在。如果不存在,你可以先创建它:
shell
echo "Hello, World!" > /home/user/document.txt
- 创建软链接:
- 使用 ln -s 命令在 /data 分区中创建一个指向 /home/user/document.txt 的软链接。
- 该命令的格式为 ln -s [源文件] [链接文件]:
shell
ln -s /home/user/document.txt /data/link_to_document.txt
这条命令会在 /data 目录下创建一个名为 link_to_document.txt 的软链接,指向 /home/user/document.txt。
- 验证软链接 : 检查软链接是否正确创建,你可以使用 ls -l 命令查看链接详情:
shell
ls -l /data/link_to_document.txt
输出将显示软链接的信息,包括它指向的源文件路径。你应该会看到类似这样的输出:
shell
lrwxrwxrwx. 1 user user 23 Oct 1 12:00 /data/link_to_document.txt -> /home/user/document.txt
其中 lrwxrwxrwx 表示这是一个软链接,-> 后面跟的是链接指向的目标文件
本文总结:
追求卓越的时候,当然要有远大的梦想,这没错。
但是,更重要的是得脚踏实地,知道自己的真实水平和能达到的目标在哪里。
千万别眼高手低,那样你可能不仅达不到你的目标,还容易错过真正的成长机会。
学习Linux命令也是一样,看似不起眼的一些命令,其实是我们学习Linux最重要的部分,因为只有掌握了基础,你才有向更高层次上升的可能。
所以期望大家能够跟着文章中的命令自己动手实操一下,一步步往前走,慢慢地让梦想和现实靠近。
这样做,你会发现自己在稳步前进中不断进步,最终能够达到那些初看似乎遥不可及的目标。
最后说一句(求关注,求赞,你的鼓励是我最大的动力)
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
本文,已收录于,我的技术网站 cxykk.com【程序员编程资料站】,有大厂完整面经,工作技术,架构师成长之路,等经验分享
求一键三连:点赞、分享、收藏
点赞对我真的非常重要!在线求赞,加个关注我会非常感激!