Linux文件系统的实验

Linux硬、软连接

  • 硬连接:指向了同一个物理位置。建立连接之后,INODE是一样的,引用的个数增加。删掉原始的文件,只是把引用删除了。下面图片的1和2就是指物理文件被引用的个数,删除其中一个引用个数就是1了。而且stat显示的两个文件的INODE是一样的
    • ln /root/a.txt /root/ss.txt
  • 软连接:指向了同一个物理位置,建立连接之后,INODE是不一样的,引用的个数没变化。删除原始文件的时候当前的软连接就会飘红报错
    • ln -s /root/a.txt /root/ss.txt

1617444289987-701aad92-7018-452a-8219-eb437bc160ea.png

1617444152842-e2f71b7a-658b-4e08-b60d-9b6ddb90d6d3.png

实验--自建文件系统挂载到系统目录

一个命令:dd

复制文件并对原文件的内容进行转换和格式化处理

[root@localhost text]# dd if=/dev/zero of=sun.txt bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.006107 seconds, 172 MB/s

[root@localhost text]# du -sh sun.txt 
1.1M    sun.txt

该命令创建了一个1M大小的文件sun.txt,其中参数解释:

  • if 代表输入文件。如果不指定if,默认就会从stdin中读取输入。
  • of 代表输出文件。如果不指定of,默认就会将stdout作为默认输出。
  • bs 代表字节为单位的块大小。
  • count 代表被复制的块数。
  • /dev/zero 是一个字符设备,会不断返回0值字节(\0)。

一个命令:losetup

让用户得以将文件 视为硬盘驱动器,光驱或软驱等设备,并挂入当作目录来使用。

使用 losetup将磁盘镜像文件虚拟成块设备,注意/dev下面放的都是设备。

losetup /dev/loop0 ~/disk02.img

一个命令:mke2fs

创建磁盘分区上的“etc2/etc3”文件系统

mke2fs  /dev/loop0

就是将这个块设备/dev/loop0格式化为这个文件系统格式

实验过程:

新建空的镜像文件,变成虚拟的块设备格式化之后挂载到硬盘上的VFS的/mnt/ooxx

# 通过自己创建磁盘镜像文件,挂载到vfs目录中,进行目录文件操作:
dd if=/dev/zero   of=~/disk02.img bs=1048576 count=100

losetup /dev/loop0 ~/disk02.img
mke2fs  /dev/loop0
mkdir /mnt/ooxx
mount -t ext2 /dev/loop0 /mnt/ooxx

cd /mnt/ooxx
mkdir bin lib64
whereis bash
# ldd命令 用于打印程序或者库文件所依赖的共享库列表。
ldd /bin/bash
cp /bin/bash bin
# 不能出现空白符号,拷贝bash的依赖
cp /lib64/{libtinfo.so.5,libdl.so.2,libc.so.6,ld-linux-x86-64.so.2}  lib64
chroot ./
echo "aaa" > /abc.txt
exit

# 查看当前位置的文件(当前位置是自己创建的bash的根目录)
cat abc.txt

一个命令:lsof (进程 + 文件描述符 + offset)

不同进程会针对同一个文件维护一个各自的文件描述符FD以及文件指针offset

一切皆文件,文件描述符FD都可以描述他们

展示进程打开了哪些文件,列出指定进程号所打开的文件:

lsof -p $pid

# 列出当前bash 进程打开的文件, $$ 就是bash进程
lsof -p $$

1617499425513-2d15c2d1-73b8-440d-8ecf-fa6523e26b2f.png

用文件描述符表示一个普通的文件

文件描述符FD:打开的文件的描述,供进程来使用,每一个bash都是一个新的进程。fd,文件描述符代表打开的文件,有inode号和seek偏移指针的概念

任何文件都0,1,2三个文件描述符FD****,表示文件的标准输入(0),标准输出(1),报错输出(2)

# 新建一个只读文件描述符8,
exec 8< a.txt

# 查看当前bash进程的文件描述符
cd /proc/$$/fd
[root@localhost fd]# ll
总用量 0
lrwx------. 1 root root 64 3月  29 21:36 0 -> /dev/pts/0
lrwx------. 1 root root 64 3月  29 21:36 1 -> /dev/pts/0
lrwx------. 1 root root 64 3月  29 21:36 2 -> /dev/pts/0
lrwx------. 1 root root 64 3月  29 21:36 255 -> /dev/pts/0
lr-x------. 1 root root 64 3月  29 21:48 8 -> /root/lab/a.txt

1617500616869-906f2833-501d-4620-81a6-54d66cafb9b2.png

两个进程都可以打开这个文件,但是每一个进程各自会维护自己的指针:

# read a 来自于 8号文件描述符,回车就不读了,所以只是读取第一行
read a 0<& 8

此时查看lsof中的偏移量就是4,但是新打开一个bash之后,一个新的文件描述符指向这个文件的时候,查看对应的偏移量就是0,所以不同进程之间对于同一个文件的描述符以及偏移量是进程隔离的,二者不会互相影响。(类似于java中的迭代器)

1617500874025-9fd205e6-2106-4bf7-9249-bd6126bcfe12.png

用文件描述符表示socket

# 文件描述符8 输入输出 指向 socket 
exec  8<>  /dev/tcp/www.baidu.com/80

1617501304266-c1de31e5-088f-4361-b2fa-48411e70e4aa.png

/proc

  • 内核映射目录,内核的一些属性。
  • 系统的变量属性,进程的在这里都会在这里被映射成文件
  • 只有开机之后才存在。
  • /proc/$$ 获取和你当前交互的进程的ID号,$BASHPID 也可以获得
  • /proc/$$/fd 目录下是当前进程的所有文件描述符
    • lsof -op $$ 更加细节,查看当前进程打开文件的文件描述符的细节

重定向操作符

不是命令,而是机制

File ifile  =  new File("/ooxx.txt")
out (fd) = new outputstream(ifile)
out.write("fdsfsdf")

上面的java程序在Linux中执行的时候,out会变成一个文件描述符指向ooxx.txt文件

文件描述符FD:打开的文件的描述,供进程来使用,每一个bash都是一个新的进程。

任何文件都0,1,2三个文件描述符FD****,表示文件的标准输入(0),标准输出(1),报错输出(2)

  • 输出重定向: > ,注意写的时候左边的文件描述符不能有空格
  • 输入重定向: <
# 标准输出1指向屏幕
ls ./ 1> ./a.txt
# 将标准输入变成这个文件,标准输出指向一个文件,就不会是屏幕了
cat 0< a.txt 1> b.txt

# 正常输出在a, 错误输出在b
ls ./ /deltaqin 1> a.txt 2> b.txt

# 从右往左执行,正常的输出覆盖了错误输出
ls ./ /deltaqin 1> a.txt 2> a.txt

# 如果重定向符号的右边是文件描述符而不是文件名需要加上 &
# 2指向了1的位置,1的位置改了,就没有
ls ./ /deltaqin 2>& 1 1> b.txt

# 将错误信息和正常的信息都放到了a.txt(从右往左执行)
ls ./ /deltaqin 1> a.txt 2>& 1

head 与 tail

head -2 a.txt
tail -2 a.txt
# 查看某一行
head -8 a.txt | tail -1

一个命令:pstree

查看进程之间的父子关系

1617502539345-bf0e72d9-ed4d-4971-8a21-77afa71fbb26.png

1617502702767-c9f7ba34-2641-4cdf-bdbb-778b07c5ba15.png

环境变量 export

将变量设置为环境变量,而不是只对当前进程有效,创建了子进程就不能用了

使用export就可以让子进程也可以获得这个变量的值

管道 |

1617503339056-5f1fe2cc-0de4-4f44-8b9b-775a539df840.png

使用lsof查看详细的文件描述符信息

1617503447055-4e580aab-cc16-457e-93b3-fba9e32d5b90.png

# 左边一个子进程,右边一个子进程,如果父进程有一个变量a,是不会被改变的
{ a=9; echo="deltaqin";} | cat

# 先看到 $$ ,后看到管道,输出父进程的pid
echo $$  |  cat

# 先看到管道,后看到BASHPID,输出子进程的pid
echo $BASHPID |  cat

# 当前bash父进程会生出两个子进程,
{ echo $BASHPID ;  read x;  }  |  { cat ; echo $BASHPID ;  read y; }

posted on 2025-10-12 21:42  chuchengzhi  阅读(13)  评论(0)    收藏  举报

导航

杭州技术博主,专注分享云计算领域实战经验、技术教程与行业洞察, 打造聚焦云计算技术的垂直博客,助力开发者快速掌握云服务核心能力。

褚成志 云计算 技术博客