文件、目录与文件系统

目录、权限与文件类型

目录与路径

  1. cd pwd mkdir rmdir
  2. mkdir -m 711 test , mkdir -p -m mkdir -m 711 test/test/test/test1 (仅test1 为711)
  3. rmdir -p test/test/test/test1 (递归删除空目录)

根目录下的标准目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 一般情况下
lrwxrwxrwx. 1 root root 7 Feb 2 14:33 bin -> usr/bin #bin 放用户可用,启动时会用到的命令 l 连接文件 指向 /usr/bin
dr-xr-xr-x. 6 root root 4096 Feb 20 10:37 boot # 开机用到的文件,内核,相关设置
drwxr-xr-x. 19 root root 3560 Apr 22 16:07 dev # 任何设备与接口设备
drwxr-xr-x. 93 root root 12288 May 24 16:05 etc # 配置文件
drwxr-xr-x. 6 root root 4096 May 24 14:42 home # 默认用户主文件夹
lrwxrwxrwx. 1 root root 7 Feb 2 14:33 lib -> usr/lib #系统函数库
lrwxrwxrwx. 1 root root 9 Feb 2 14:33 lib64 -> usr/lib64
drwx------. 2 root root 16384 Feb 2 14:32 lost+found # 文件系统发生错误时,保存的一些丢失片段
dr-xr-xr-x. 9 root root 2048 Jan 15 21:24 media # 可删除设备
drwxr-xr-x. 2 root root 4096 Jun 25 2018 mnt # 额外挂载设备
drwxr-xr-x. 7 root root 4096 May 24 16:16 opt # 第三方软件放置库
dr-xr-xr-x. 505 root root 0 Feb 19 17:39 proc #虚拟文件系统,内核进程网络状态等存在于内存中,不占磁盘空间
dr-xr-x---. 4 root root 4096 May 24 14:54 root # 系统管理员主文件夹
lrwxrwxrwx. 1 root root 8 Feb 2 14:33 sbin -> usr/sbin # 开机过程需要的命令
drwxr-xr-x. 3 root root 4096 May 24 14:39 srv # 服务数据目录
dr-xr-xr-x. 13 root root 0 Feb 19 17:40 sys # 同proc ,目前已加载的内核模块,与内存监测到的硬件设备信息等。
drwxrwxrwt. 25 root root 4096 May 24 16:44 tmp # 临时放置文件
drwxr-xr-x. 14 root root 4096 Feb 2 14:33 usr # 可分享不可变动的,所有系统默认软件等
drwxr-xr-x. 21 root root 4096 Feb 20 10:37 var # 缓存,登录文件以及某些软件运行所产生的文件等。

划分这些目录的两条依据:

可变动的,不可变动的

可分享的,不可分享的

文件类型与查询

上面 ls -l 每行开头的那个字符就是文件类型,d 是目录,l 是连接文件,- 是普通文件。想看得更准就用 file

  1. file /user/bin/passwd # 查询某文本数据类型
  2. which python # 查询某命令位置
  3. whereis passwd # 查询某目录,文件位置
  4. locate passwd # -i 忽略大小写 -r 接正则表达式
  5. find # 能执行额外的动作

权限:用户与用户组

ls -l 开头那串 rwxr-xr-x 就是权限,按 拥有者/用户组/其他人 三组各三位来读。

  1. u g o a (user group other all)
  2. r:4 w:2 x:1
  3. chgrp chown chmod

内存交换空间(swap)

CPU读取的数据都来自于内存,内存不足时,内存中暂不使用的程序和数据会被移动到swap中

Linux 所有的文件都建立在虚拟文件系统( Virtual File System ,VFS )之上

Linux 上不同的目录可能是不同的磁盘,不同的文件可能是不同的设备。

分区结构

1
2
3
4
5
6
7
8
9
10
11
root@instance-1:~# df -hT
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 799M 81M 718M 11% /run
/dev/sda1 ext4 9.7G 3.7G 5.6G 40% /
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda15 vfat 124M 7.9M 116M 7% /boot/efi
tmpfs tmpfs 799M 0 799M 0% /run/user/0
/dev/sdb ext4 20G 45M 19G 1% /mnt/etcd_data

这块盘用的是 GPT 分区表(下面 fdisk -lDisklabel type: gpt),/dev/sda1/dev/sda14/dev/sda15 是三个平级的分区,分别对应 BIOS bootEFI System 和根文件系统,GPT 下没有主分区/扩展分区/逻辑分区之分,分区表一般预留 128 个表项,也就是最多 128 个平级分区,编号只是表项序号,跟分区类型无关。看起始扇区也能确认:sda1262144 开始,而 sda158192~262143,整个排在 sda1 前面,谈不上被谁包含,lsblk 里三者也是并列的。「1~4 是主分区、4 以上是逻辑分区」这套编号规则只适用于 MBR/DOS 分区表,而且逻辑分区是寄居在扩展分区里的,不是挂在主分区下面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
root@instance-1:~# fdisk -l
Disk /dev/sda: 10 GiB, 10737418240 bytes, 20971520 sectors
Disk model: PersistentDisk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 3948AFEB-2993-D54E-A66C-392005D28B38

Device Start End Sectors Size Type
/dev/sda1 262144 20971486 20709343 9.9G Linux filesystem
/dev/sda14 2048 8191 6144 3M BIOS boot
/dev/sda15 8192 262143 253952 124M EFI System

Partition table entries are not in disk order.


Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: PersistentDisk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x19fbd859

Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 41943039 41940992 20G 8e Linux LVM

lsblk 命令 用于列出所有可用块设备的信息,而且还能显示他们之间的依赖关系,但是它不会列出 RAM 盘的信息

1
2
3
4
5
6
7
8
root@instance-1:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 10G 0 disk
├─sda1 8:1 0 9.9G 0 part /
├─sda14 8:14 0 3M 0 part
└─sda15 8:15 0 124M 0 part /boot/efi
sdb 8:16 0 20G 0 disk
└─sdb1 8:17 0 20G 0 part

挂载

不同的目录可以采用不同的文件系统
mount -l 查看已经挂载的文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
root@k8s03:~# mount -l
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=233816k,nr_inodes=58454,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=49732k,mode=755)
/dev/vda5 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=33,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=9534)
mqueue on /dev/mqueue type mqueue (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)
/dev/vda1 on /boot type ext2 (rw,relatime)
tracefs on /sys/kernel/debug/tracing type tracefs (rw,relatime)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=49728k,mode=700)

sysfs proc devtmpfs tmpfs ext4 都是不同的文件系统

docker 的文件系统 AUFS, overlay2, devicemapper

sysfs : 让用户通过文件访问和设置设备驱动信息。

proc : 是一个虚拟文件系统,让用户可以通过文件访问内核中的进程信息。

devtmpfs : 在内存中创造设备文件节点。

tmpfs : 用内存模拟磁盘文件。

ext4 : 是一个通常意义上我们认为的文件系统,也是管理磁盘上文件用的系统。

fdisk /dev/sdb 分区

mkfs -t ext4 /dev/sdb1 格式化(顺序是先分区再格式化,而且格式化的是分区,不是整盘)

mount /dev/sdb1 /mnt/etcd_data/ 挂载命令

umount /mnt/etcd_data/ 取消挂载

如果不打算分区,也可以整盘直接用:mkfs -t ext4 /dev/sdb 之后 mount /dev/sdb /mnt/etcd_data/。两种做法二选一,不要混着来 —— 本文开头 df -hT 里挂的是整盘 /dev/sdb、类型 ext4,而 fdisk -l 又还留着一条 8e Linux LVM/dev/sdb1lsblksdb1 也没有挂载点,这就是混用留下的痕迹:ext4 的超级块在 1024 字节偏移处,并没有覆盖掉开头的分区表,于是那张过期的分区表就一直压在整盘文件系统上面。

磁盘被手动挂载之后都必须把挂载信息写入 /etc/fstab 这个文件中,否则下次开机启动时仍然需要重新挂载。

文件系统区别

内存可以支持到字节级别的随机存取,而这种情况在硬盘中通常是不支持的

为了提高性能,通常会将物理存储(硬盘)划分成一个个小块,比如每个 4KB

FAT inode 日志文件系统(NTFS, EXT3、4)

硬链接与 软连接

硬链接 多个文件共享 inode

1
2
3
4
5
6
7
root@instance-1:~# echo hello > a.txt
root@instance-1:~# cat a.txt
hello
root@instance-1:~# ln a.txt b.txt
root@instance-1:~# rm -rf a.txt
root@instance-1:~# cat b.txt
hello

软链接拥有自己的 inode,但是文件内容就是一个快捷方式。源文件删除 其对应的 inode 也就被删除了,软链接指向了一个空地址

1
2
3
4
5
6
root@instance-1:~# ln -s b.txt  c.txt
root@instance-1:~# cat c.txt
hello
root@instance-1:~# rm -rf b.txt
root@instance-1:~# cat c.txt
cat: c.txt: No such file or directory

日志文件系统

NTFSExt3 等是日志文件系统,它们和 FAT 最大的区别在于:数据照样要写到磁盘上,只是在改动落到最终位置之前,先把这次变更以预写日志(journal)的形式记一笔。日志写入是追加式的,不用考虑数据的覆盖,但关键点不是「定期写入磁盘」,而是提交前必须先落盘并保证顺序(write barrier),否则日志本身就不可信。崩溃之后重放日志,就能把文件系统恢复到一致状态,不必再全盘 fsck。日志空间是循环复用的,回放完就丢弃,留不下「一段时间内的还原点」,那是快照要解决的问题。所以日志换来的是崩溃一致性和快速恢复,代价是相对无日志的文件系统多了一份写放大,并不是「大大提高性能」。顺带一提,ext2 恰恰是没有日志的,日志要到 ext3 才引入。

分布式文件系统

分布式文件系统 : 通过计算机网络连接大量物理节点,将不同机器、不同磁盘、不同逻辑分区的数据组织在一起,提供海量的数据存储(一般是 Petabytes 级别,1PB = 1024TB)。

分布式数据库 : 在分布式文件系统基础上,提供应对具体场景的海量数据解决方案

一个读取的示例

1
2
3
4
5
6
7
8
9
客户端想要读取/foo/bar中某个 Chunk 中某段内容(Byterange)的数据,会分成 4 个步骤:

客户端向 Master 发送请求,将想访问的文B件名、Chunk 的序号(可以通过 Chunk 大小和内容位置计算);

Master 响应请求,返回 Chunk 的地址和 Chunk 的句柄(ID);

客户端向 Chunk 所在的地址(一台 ChunkServer)发送请求,并将句柄(ID)和内容范围(Byterange)作为参数;

ChunkServer 将数据返回给客户端。

文件误删后的恢复

文件当前正在被进程使用

使用 lsof

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@instance-2 ~]# rm -rf test.txt
[root@instance-2 ~]# lsof |grep test.txt
tail 31397 root 3r REG 8,2 5 50674099 /root/test.txt (deleted)
[root@instance-2 ~]# cd /proc/31397/fd
[root@instance-2 fd]# ls -l
total 0
lrwx------ 1 root root 64 Feb 21 15:42 0 -> /dev/pts/0
lrwx------ 1 root root 64 Feb 21 15:42 1 -> /dev/pts/0
lrwx------ 1 root root 64 Feb 21 15:42 2 -> /dev/pts/0
lr-x------ 1 root root 64 Feb 21 15:42 3 -> /root/test.txt (deleted)
lr-x------ 1 root root 64 Feb 21 15:42 4 -> anon_inode:inotify
[root@instance-2 fd]# cp 3 ~/test.txt.bak
[root@instance-2 fd]# cat ~/test.txt.bak
test

文件未被进程使用

extundelete