Linux 系统编程:文件系统
文件类型
Linux 文件分为 3 类:
普通文件
:文本文件、二进制文件,要学习如何创建、复制、移动、重命名和删除这样的文件。目录
(Windows 中的“文件夹”与之类似)伪文件
:设备文件、命名管道、proc 文件,不存储数据,因此不占用任何空间。- 设备文件:物理设备的内部表示,键盘、打印机、磁盘驱动器都可以当做特殊文件来访问
- 命名管道:将一个程序的输出连接到另一个程序的输入上
- proc 文件:访问内核中的信息,最初这些文件用来提供正在运行的进程(process)的信息,因此命名为“proc” 。
目录
目录
将文件组织成一个类似树的层次系统。父目录
是包含其他目录的目录。 子目录
是位于另一个目录中的目录。
通常在谈论目录时就好像目录中实际包含其他文件一样。实际上,所有的文件都存储为一个单独的实体。目录并不存放实际文件,它只是包含 Linux 定位文件所需的信息。
设备文件
设备文件
是表示物理设备的伪文件。Linux 将所有的设备文件存放在 /dev
目录中。这是单词 device
(设备)的简称。
硬件设备文件
/dev/hda
:IDE 硬盘/dev/hda1
:IDE 硬盘第 1 分区/dev/sda
:SATA/SCSI 硬盘/dev/sda1
:SATA/SCSI 硬盘第 1 分区/dev/nvme0n1
:NVMe 固态硬盘的第 1 个物理驱动器/dev/lp0
:打印机
硬盘按其结构原理分为机械硬盘(HDD)、固态硬盘(SSD)和混合硬盘(SSHD)。
按接口类型分为:IDE、SATA、SCSI、SAS、PCIE、M.2 等。
M.2 接口是专门为固态硬盘准备的新接口,本质上是一个 PCIe 插槽,支持 NVMe 协议。
更详细的硬盘接口参考 这里。
终端
/dev/tty
:当前终端,示当前正在运行的进程所在的控制台终端设备。/dev/tty1
:控制台终端(一般是显示屏)/虚拟控制台/dev/pts/0
:伪终端,GUI 中打开的终端窗口、远程连接到主机的终端
使用
tty
命令显示终端的名称
伪设备
伪设备是一个文件,充当输入源或输出目标。伪设备并不对应于实际设备。
/dev/null
:它被用来丢弃所有写入它的数据,读取它会立即返回EOF(文件结束)。通常用于丢弃不需要的输出数据,例如在命令行中执行命令时,可以将不需要的输出重定向到 /dev/null。/dev/zero
:放弃输出,输入返回和请求一样多的字符,它们都是 null (二进制的 0),/dev/zero 通常用于生成无限数量的二进制 0,例如生成大量的零填充数据。/dev/random
:随机数生成器,使用物理噪声源,随机数质量高,生成慢,适合高安全性场合。/dev/urandom
:随机数生成器,使用伪随机数生成器,随机数质量低,生成快,适合一般场合。
命令管道
提取系统口令文件中所有包含字符串“bash”的行,然后通过管道传送给 wc 程序统计这些行的数量:
grep bash /etc/passwd | wc -l
这里面的管道没有具体名字,称为匿名管道。使用下面的命令可以创建一个名为 fifotest
的命名管道:
mkfifo fifotest
grep bash /etc/passwd > fifotest
之后终端会进入阻塞状态,此时再打开一个终端,在终端中使用 wc -l < fifotest
来从命名管道读取数据。注意命名管道是单向的,其中的数据是先进先出的。删除命名管道使用 rm fifotest
。
- 打开终端 1,新建命名管道:
mkfifo fifotest
,然后输入echo "Hello pipe" > fifotest
- 打开终端 2,输入
grep bash /etc/passwd > fifotest
- 打开终端 3,输入
cat fifotest
会显示:
Hello pipe
root:x:0:0:root:/root:/bin/bash
zhg:x:1000:1000:ubuntu-20.4,,,:/home/zhg:/bin/bash
文件结构层次
Linux 目录结构遵循 文件系统层次结构标准
(FHS),它由 Linux 基金会维护。最新版本为 3.0,于 2015 年 6 月 3 日发布。具体内容可以参考维基百科词条:《Filesystem Hierarchy Standard》。下图展示了标准 FHS 的目录结构。从图中可以看出,所有文件和目录都显示在根目录 /
下,即使它们存储在不同的物理或虚拟设备上。
目录 | 描述 |
---|---|
/ | 根目录(root directory),文件层次结构的根目录 |
/bin | 为所有用户提供的基本且必须的二进制文件,在系统启动时需要执行其中的程序。比如 cat 、ls 、cp 命令 |
/boot | 引导加载程序,比如内核 |
/dev | 设备文件,比如 /dev/null 、/dev/sda1 |
/etc | 静态配置文件,一般是 “Editable Text Configuration” 的简称。 配置文件是某程序启动时处理的文本文件,其中包含有影响程序操作的命令或信息。 |
/home | 用户的 home 目录,存放个人文件和目录的位置。 |
/lib | 库文件,是 /bin 和 /sbin 目录内的程序所需的库。有一些库支持 32 位或 64 位版本指令集,这些库可能放在 /lib32 或者 /lib64 内。 |
/media | 可移动介质挂载点。可移动介质是诸如 CD-ROM、SD 卡之类的。 |
/mnt | 临时挂载的文件系统 |
/opt | 保留用于安装附加应用程序软件包 。opt 是“optional software”的缩写。这就给予应用程序开发人员一个指定的位置来安装他们的软件。在 /opt 中,每个程序都根据自己的需要拥有自己的子目录。 |
/proc | 以文件形式提供进程和内核信息的虚拟文件系统 |
/root | root 用户的 home 目录 |
/run | 运行时的变量数据:自系统启动以来正在运行的系统信息。 |
/sbin | 基本且必须的系统二进制文件,比如 fsck 、init 命令 。通常,这个目录中的程序必须由超级用户运行。 |
/srv | 保存特定的服务数据,srv 是单词 service 的缩写。比如保存 FTP 服务器的数据或者版本控系统的存储库。 |
/sys | 包含一些信息,有关设备、驱动和某些内核特性 |
/tmp | 保存临时文件,任何人都可以在这个目录中存储文件。但是,最终这些文件会自动移除,一般重启后会丢弃掉 。 |
/usr | 辅助层次的、只读的用户数据。包含用户自己实用工具和应用程序。这些应该是可共享和只读的。 |
/usr/bin | 不重要的二进制文件,可用于所有用户。注意这个目录中的程序和命令通常与系统的基础功能和应用程序相关,而不是与特定的用户或应用程序相关。实际上,在我的 ubuntu 20.4 系统上, /bin 目录实际上连接到了 /usr/bin ,也就是说打开 /bin 目录,实际上打开的是 /usr/bin 目录。 |
/usr/include | 标准头文件 |
/usr/lib | 库文件,是 /usr/bin 和 /usr/sbin 目录内程序不可缺少的库。有一些库支持 32 位或 64 位版本指令集,这些库可能放在 /usr/lib32 或者 usr//lib64 内。实际上,在我的 ubuntu 20.4 系统上, /lib 目录实际上连接到了 /usr/lib ,也就是说打开 /lib 目录,实际上打开的是 /usr/lib 目录。 |
/usr/libexec | 由其它程序运行的二进制文件,用户或 shell 脚本不应该直接执行这些程序。 |
/usr/local | 用于存放本地安装的软件和程序。软件通常是手动编译和安装的,或者是从源代码手动构建的。/usr/local 目录下通常包含各种子目录,例如 bin、include、lib 等,用于存储可执行文件、头文件和库文件等。 |
/usr/sbin | 不重要的系统二进制文件。实际上,在我的 ubuntu 20.4 系统上, /sbin 目录实际上连接到了 /usr/sbin ,也就是说打开 /sbin 目录,实际上打开的是 /usr/sbin 目录。 |
/usr/share | 与架构无关的共享数据 ,包含文档、字体、图标等。比如,/usr/share/dict/words 是字典文件、/usr/share/man 存储 man 命令用到的手册、/usr/share/info 存放 info 命令用到的手册。 |
/usr/src | 源代码,比如内核源码及其头文件 |
/var | 是“variable”的简称。存放系统运行时需要的一些动态数据,例如日志文件、缓存文件和待处理的任务文件等。/var 目录和 /usr 目录具有相似的功能,都是辅助文件系统的根,不同的是,/usr 保存的是不可变的静态数据,而 /var 保存的是可变数据。通过这种方式,将静态数据和可变数据分离开来,可以使系统易于管理。 |
/var/cache | 应用程序缓存数据。此类数据是由于耗时的 I/O 或计算而在本地生成的。应用程序必须能够重新生成或还原数据。缓存的文件可以在不丢失数据的情况下删除。 |
/var/lock | 锁定文件。跟踪当前正在使用的资源。 |
/var/log | 日志文件。 |
/var/tmp | 重启也要保留的临时文件 |
路径和工作目录
这是一个 words 文件的路径:/usr/share/dict/words
。首先时一个 /
字符,表示根目录,然后是到达 words 文件途径的所有目录名,每个目录名后面跟着一个 /
,最后是文件名。
Linux 允许指定一个目录为 工作目录
(也称为 当前目录
)。使用工作目录中的文件时,无需指定整个路径,只需键入文件名即可。
如果目录序列从根目录开始,称为 绝对路径名
:/usr/share/dict/words
如果目录序列从工作目录开始,称为 相对路径名
:dict/words
三种路径名缩写:
..
:指父目录.
:指工作目录本身~
:指 home 目录
.
和..
实际上是目录条目,由文件系统自动创建。系统中的每个目录都包含有这两个条目。
~
是 shell 提供的抽象概念,是为了方便引用 home 目录而提供的。
Linux 系统中,shell 使用一个特殊的环境变量 PATH 来决定在哪些目录中查找可执行文件。出于安全考虑,当前目录(.)通常不包含在这个 PATH 变量中。因此,仅仅输入程序名(例如my_program)而不指定路径的话,shell 会在 PATH 指定的目录列表中查找 my_program,但不会在当前目录下查找。使用 ./
明确告诉 shell 在当前目录下查找并执行该文件。
目录操作命令
显示工作目录名称:pwd
显示工作目录的名称, pwd
是 print working directory 的缩写。
切换目录:cd
切换工作目录,change directory。
cd /bin
:使用绝对路径切换cd bin
:使用相对路径切换,当前工作目录中要有子目录 bincd
:切换到 home 目录(另一种方法是:cd ~
)cd -
:切换到上一次访问的目录cd ..
:切换到父目录
创建新目录:mkdir
文件名区分大小写。
mkdir bin etc
:创建 bin 和 etc 目录mkdir /home/zzch/bin
:使用绝对路径创建目录(父目录 /home/zzch 必须存在)mkdir -p /home/zzch/bin
:-p
选项自动创建所有需要的父目录(make parent)
删除目录:rmdir
只有当一个目录为空的时候,才能删除这个目录。不能删除工作目录和根目录之间的任何目录。
rmdir bin
:删除目录 bin,bin 必须是空目录rmdir -p /home/zzch/bin
:-p
选项自删除除所有需要移除的父目录
rm -r
移除所有子目录及其内容。
移动或重命名目录:mv
语法:mv directory target
- 移动后,原位置的目录将不存在,同时移动目录中所有的文件和子目录
- 如果新位置和原位置在同一个目录中,实际结果就是对原目录重命名
- 还可以移动或重命名文件
显示目录内容信息:ls
list files:列举文件
ls
:以列的形式按字母表顺序显示当前目录的文件名称,当将 ls 的输出重定向到文件或管道线时,ls 以每个文件名占一行的形式输出结果。ls -t
:以时间顺序显示当前目录的文件名,默认是文件最后一次修改的时间。如果想按照最后一次读取文件的时间排序,使用-tu
选项ls -l
:以长列表的形式显示ls -1
:每个文件名占一行的形式输出(注意选项是数字 1)ls -a
:显示隐藏文件,a 指 all files,全部文件。(ubuntu 文件管理器中,快捷键Ctrl + h
显示隐藏文件,这里 h 指 hide)ls /bin /etc
:显示 bin 和 etc 目录汇总的文件名称ls -R /bin
:列举 bin 目录中的所有直接或间接的子目录和文件信息。(R 表示 recursive,递归)ls -s /bin
:显示 bin 目录内的文件和目录的大小(s 指 size),ls -sh /bin
以适合人类阅读的方式显示(h 指 human)。注意:ls -s
不统计子目录内的文件大小,因此子目录一般都是显示 4KB。ls -sSh /bin
:按照文件大小降序、以适合人类阅读的方式显示 bin 目录内的文件和文件夹(S 指 Sort,排序)。按照文件大小升序显示选项为-r
(r 指 reverse,相反)
区域设置:
locale 查看环境变量的值,排序序列变量是 LC_COLLATE。
如果 LC_COLLATE = “C”,字母排序和 ASCII 码相同:ABCDEF…abcdef…
如果 LC_COLLATE = “en_US”,字母排序和字典相同:aAbBcCdDeEfF…
长列表输出解析:
total 8
drwxrwxr-x 3 zhzhchang jack 4096 Dec 31 18:06 target
-rw-rw-r-- 1 zhzhchang jack 59 Oct 23 05:48 tmp.txt
- 最右边是文件名,比如 target 和 tmp.txt
- 文件名的左边是时间和日期,默认是修改时间,可以使用
-lu
选项显示文件的读取时间。 - 在日期的左边,是以字节为单位的文件大小,可以使用
-lh
以适合人类阅读的方式显示文件大小。注意,文件大小是文件的实际数据量,而不是文件占用的存储空间。
注意 target 目录的大小是 4K。这是因为我测试用的系统使用 4K 大小的分配单元,而且每个目录最少使用 1 个分配单元。重要的是记住 数量 4K 指的是目录本身的大小,而不是目录内容的大小。尽管我们在谈论目录时,就好像它“包含”大量文件,其实这只是一个隐喻。目录只占用少量的存储空间,因为它们包含的是有关文件的信息,而不是文件本身。 - 一行的第一个字母指示文件类型:
-
:常规文件d
:目录l
:符号连接(小写字母 l)b
:块设备(特殊文件)c
:字符文件(特殊文件)p
:命名管道/FIFO
- 在文件大小的左边是两个名称:文件属主的用户标识和用户标识所属的组。在本例中,所有文件由用户标识 zhzhchang 拥有,而 zhzhchang 位于 jack 组中。
- 用户标识的左边的数字显示文件由多少个链接
- 链接数的左边是 9 个字符的字符串,显示文件的权限。
查看磁盘使用:du
disk usage:磁盘使用,汇总文件集的磁盘使用情况,递归地用于目录。
du file-name
:查看指定文件大小,选项-h
以适合人类阅读方式显示。du -h /etc
:查看指定目录内的文件大小,会递归的用于子目录。这跟ls -hs
不统计子目录内的文件不同。du -hd1 /etc
:指定递归的子目录深度为 1 。d 表示 depth,深度,后面跟的数字表示递归子目录的深度。虽然本例只显示一级子目录,但统计的文件大小仍包含所有文件的大小。du -hs /etc
:s 选项只显示目录 etc 的总和(sum),包括子目录内的所有文件和目录。(只统计总和时,如果遇到权限问题会输出错误信息,通常将错误信息重定向到位桶:du -hs /etc 2> /dev/null
)du -hd1 /etc | sort -h
:以适合人类阅读的方式显示、只递归 1 级子目录,结果按照文件大小排序
查看磁盘可用空间:df
disk free-space:磁盘可用空间
df -h
:以适合人类阅读的方式显示输出。h 表示 human。df -i
:显示文件系统的 inode 使用情况
读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!