树莓派与Linux——Linux文件管理

  1. 树莓派与Linux——Linux文件管理
    1. 1、路径与文件
    2. 2、目录
    3. 3、硬链接
    4. 4、软链接
    5. 5、文件操作
    6. 6、文件搜索

树莓派与Linux——Linux文件管理

本文大部分内容参考自《树莓派开始,玩转Linux》第十五章,作者: vamei & 周昕梓,下文中出现的全部的回显都是本人实际操作后的返回结果。

对于计算机来说,所谓的数据就是0和1的序列。Linux上的文件提供了数据存储的基本单元。此外,文件还以目录的形式组织起来,以便用户能迅速找到所需数据。本文将深入了解文件的组织方式。

1、路径与文件

文件和文件组织构成了一个文件系统 (File System)。Linux的文件系统是一个树状结构,整个文件系统有个共同的起点,就是树状结构的顶端,如下图所示。Linux把这个起点称为根目录 (Root Directory),用符号 / 表示。

文件树的末端可能是一个普通文件,用于存储数据,比如 file.txt 。这个树上的节点还可能是一个目录,从而提供归属关系。通过归属关系,目录之间分为层级。目录 pi 称为 home子目录 (Child Directory),而目录 homepi父目录 (Parent Directory)。如果从该树中截取一部分,比如从目录pi开始往下,实际上也构成一个有单一起点的子文件树。

要找到一个文件,除了要知道该文件的文件名,还需要知道从根目录到该文件的所有目录名。从根目录开始的所有途径的目录名和文件名构成了一个路径。在上图的文件系统中,从顶端的根目录 / ,沿箭头标出的路径,经过目录 homepidoc ,最终可以找到文件 file.txt 。因此,为了找到文件 file.txt ,我们需要知道完整的路径,也就是绝对路径 /home/pi/doc/file.txt

2、目录

在Linux系统中,目录把文件组织起来。其实,目录本身也是一种特殊的文件,而 /home/pi/doc 是指向目录文件 doc 的绝对路径。我们可以使用file命令来获取文件类型,如下:

pi@raspberrypi:~ $ file /home/pi/doc/
/home/pi/doc/: directory

也就是说, /home/pi/doc 是一个目录文件。

作为对比,我们用file获得 /home/pi/doc/file.txt 的类型:

pi@raspberrypi:~ $ file /home/pi/doc/file.txt 
/home/pi/doc/file.txt: ASCII text

/home/pi/doc/file.txt 是一个ASCII编码的文本文件。

目录文件中的内容以条目的形式存在。它至少包含以下条目:

.   指向当前目录
..  指向父目录

除此之外,目录文件中还有属于该目录文件的文件名,比如 /home/pi/doc 中有如下内容:

pi@raspberrypi:~/doc $ ls -al
总用量 12
drwxr-xr-x  2 pi pi 4096 4月  19 20:29 .
drwxr-xr-x 27 pi pi 4096 4月  19 20:26 ..
-rw-r--r--  1 pi pi   13 4月  19 20:29 file.txt

Linux理解一个绝对路径的方式如下:先找到根目录文件,从该目录文件中读取 home 目录文件的位置,然后从 home 文件中读取 pi 的位置。通过一层层目录的查询,Linux最终会找到目录 docfile.txt 的位置。因为目录文件中都有当前目录和父目录的条目,所以我们可以在绝对路径中加入“.”或者“..”来表示当前目录或者父目录,比如 /home/./pi/doc/../home/pi 等同。

此外,当Linux程序运行时,会维护一个名为工作目录 (Present Working Directory)的变量。在Shell中,用pwd命令确定的当前目录,实际上就是Shell程序的工作目录。而所谓的变换目录,就是把一个新的目录存入该变量中,例如:

pi@raspberrypi:/ $ pwd
/
pi@raspberrypi:/ $ cd /home/pi
pi@raspberrypi:~ $ pwd
/home/pi

有了工作目录,我们就可以用相对工作路径来创建绝对路径。例如,如果工作目录是 /home/pi ,那么就可以用 doc/file.txt 来指示 /home/pi/doc/file.txt 。在Shell中输入命令时,就可以用相对路径来替换绝对路径:

pi@raspberrypi:~ $ ls doc/file.txt 
doc/file.txt

由于相对路径借用了工作目录的信息,所以在大部分情况下,相对路径都比绝对路径简短。

3、硬链接

当目录文件中增加一个文件的条目时,就建立一个指向文件的硬链接 (Hard Link)。一旦有了对应于文件的硬链接,这个文件就纳入了文件系统中。一个文件允许出现在多个目录中,这样,它就有多个硬链接。文件拥有的硬链接数目,称为文件在整个系统的链接数 (Link Count)。当文件的链接数降为0时,说明文件已经孤立于文件系统之外。这样的文件会被Linux删除。

大多数情况下,一个文件只存在于一个目录之下,所以连接数为1。在这种情况下,一旦删除目录中该文件的条目,也就是删除一个硬链接,那么该文件就会被删除。如果是文章第一张图中的文件结构,那么使用删除硬链接的unlink命令,file.txt 的条目将从目录文件 /home/pi/doc 中删除,文件的链接数降为0。在这种情况下,unlink效果等同于删除文件,如下:

pi@raspberrypi:~/doc $ ls -al
总用量 12
drwxr-xr-x  2 pi pi 4096 4月  19 20:29 .
drwxr-xr-x 27 pi pi 4096 4月  19 20:26 ..
-rw-r--r--  1 pi pi   13 4月  19 20:29 file.txt
pi@raspberrypi:~/doc $ unlink file.txt
pi@raspberrypi:~/doc $ ls -al
总用量 12
drwxr-xr-x  2 pi pi 4096 4月  19 20:40 .
drwxr-xr-x 27 pi pi 4096 4月  19 20:26 ..

如果给同一个文件在新的目录下建立硬链接,那么该文件的链接数就超过了1。我们用ln命令来创建硬链接:

pi@raspberrypi:~/doc $ ln file.txt /home/pi/Documents/another_file.txt
pi@raspberrypi:~/doc $ cd /home/pi/Documents/
pi@raspberrypi:~/Documents $ ls -al
总用量 12
drwxr-xr-x  2 pi pi 4096 4月  19 20:44 .
drwxr-xr-x 27 pi pi 4096 4月  19 20:26 ..
-rw-r--r--  2 pi pi   13 4月  19 20:39 another_file.txt

原来的文件在 /home/pi/doc 目录下。通过新建硬链接, /home/pi/Documents 也会多出一个硬链接记录。该记录的文件名是 another_file.txt ,但实际上它和 file.txt 是同一个文件。所以,对其中任意文件的修改,也会出现在另一个文件中。你可以用 nano 编辑修改 file.txt 。注意,修改会直接出现在 another_file.txt 中。

pi@raspberrypi:~/Documents $ more another_file.txt 
hello world!
pi@raspberrypi:~/Documents $ nano ../doc/file.txt 
pi@raspberrypi:~/Documents $ more another_file.txt 
hello world!
Change the world!

此时,再使用unlink命令,还可以通过 /home/pi/doc/file.txt 找到该文件,文件并没有被删除。实际上,Linux中的rm命令和unlink命令功能相同,你可以试试看。

pi@raspberrypi:~/Documents $ unlink another_file.txt 
pi@raspberrypi:~/Documents $ ls ../doc/file.txt 
../doc/file.txt

4、软链接

同一文件的多个硬链接,会破坏树状的文件系统。因此,Linux系统并不鼓励手动创建硬链接。在必要的情况下,你可以用软链接 (Soft Link)的方式,在多个目录下创建指向同一文件的链接。

软链接不影响文件的链接数。软链接本质上是一个文件,它的文件类型是symbolic link。在这个文件中,包含有链接指向的文件的绝对路径。当读写该文件时,Linux会根据软链接中的绝对路径把读写操作导向软链接所指向的文件。与Windows系统的“快捷方式”类似,Linux的软链接就是Linux的“快捷方式”。

我们在ln命令中加上-s选项,来创建软链接:

pi@raspberrypi:~/doc $ ln -s file.txt /home/pi/Documents/file-link.txt
pi@raspberrypi:~/doc $ cd /home/pi/Documents/
pi@raspberrypi:~/Documents $ ls -al
总用量 8
drwxr-xr-x  2 pi pi 4096 4月  19 20:50 .
drwxr-xr-x 27 pi pi 4096 4月  19 20:26 ..
lrwxrwxrwx  1 pi pi    8 4月  19 20:50 file-link.txt -> file.txt

/home/pi/file-link.txt 是一个软链接文件。你可以用file命令获知其文件类型:

pi@raspberrypi:~/Documents $ file file-link.txt 
file-link.txt: broken symbolic link to file.txt

此时,用 nano 编辑 file-link.txt ,相关的读写操作也会反映在原文件 file.txt 中。和硬链接不同的是,软链接不影响文件的链接数,也不会破坏文件系统的树状结构。因此,软链接在Linux中使用广泛。以Linux下常用的网络服务器程序Apache为例,它会安装许多配置文件,每种配置文件针对一种情况。但Apache只会把特定目录下的配置文件作为其要加载的配置。这时可以通过建立软链接的方式,把目标配置文件链接到该目录。这样可以避免很多对原始配置文件的误操作。

软链接本身是一个文件,但很多时候它又会指代一个原始文件。这种双重身份有时会造成困惑。我们用 nano 来编辑软链接,那么该操作会跟随链接指引,作用于原文件。如果用 rm 来删除软链接,那么删除操作不会跟随软链接。所以,删除软链接后,原文件依然存在。一个命令是否跟随链接指引,是由该命令的程序决定的。不过在大多数情况下,对文件本身的操作,如读写数据和复制文件等,会跟随指引。而对涉及文件所属目录的操作,如删除、移动等,则不会跟随指引。

5、文件操作

对于一个文件,可以有很多种操作。例如,用touch命令新建一个空的普通文件:

pi@raspberrypi:~/doc $ ls
file.txt
pi@raspberrypi:~/doc $ touch empty.txt
pi@raspberrypi:~/doc $ ls
empty.txt  file.txt

我们还可以创建一个新的目录:

pi@raspberrypi:~/doc $ ls
empty.txt  file.txt
pi@raspberrypi:~/doc $ mkdir good
pi@raspberrypi:~/doc $ ls -l
总用量 8
-rw-r--r-- 1 pi pi    0 4月  19 21:01 empty.txt
-rw-r--r-- 1 pi pi   31 4月  19 20:46 file.txt
drwxr-xr-x 2 pi pi 4096 4月  19 21:01 good

删除一个空目录:

pi@raspberrypi:~/doc $ rmdir good
pi@raspberrypi:~/doc $ ls -l
总用量 4
-rw-r--r-- 1 pi pi  0 4月  19 21:01 empty.txt
-rw-r--r-- 1 pi pi 31 4月  19 20:46 file.txt

在上次《树莓派与Linux——Shell入门》文章中,我们已经了解了复制的cp命令和删除的rm命令。这些命令除了作用于单个文件,还可以作用于从某个目录开始的整个子文件树。比如复制整个目录 /home/pi/doc

pi@raspberrypi:~/doc $ mkdir good
pi@raspberrypi:~/doc $ cd good/
pi@raspberrypi:~/doc/good $ touch file.txt
pi@raspberrypi:~/doc/good $ ls -l
总用量 0
-rw-r--r-- 1 pi pi 0 4月  19 21:13 file.txt
pi@raspberrypi:~/doc/good $ cd ..
pi@raspberrypi:~/doc $ cp -r good good_bak
pi@raspberrypi:~/doc $ ls -l
总用量 12
-rw-r--r-- 1 pi pi   31 4月  19 20:46 file.txt
drwxr-xr-x 2 pi pi 4096 4月  19 21:08 good
drwxr-xr-x 2 pi pi 4096 4月  19 21:09 good_bak
pi@raspberrypi:~/doc $ cd good_bak/
pi@raspberrypi:~/doc/good_bak $ ls -l
总用量 0
-rw-r--r-- 1 pi pi 0 4月  19 21:13 file.txt

这样,从 doc 开始的整个子文件树都将复制到 /home/pi/doc-copy

同样,我们可以删除某个子文件树:

pi@raspberrypi:~/doc/good_bak $ cd ..
pi@raspberrypi:~/doc $ rm -r good_bak/
pi@raspberrypi:~/doc $ ls -l
总用量 8
-rw-r--r-- 1 pi pi   31 4月  19 20:46 file.txt
drwxr-xr-x 2 pi pi 4096 4月  19 21:13 good

在了解了文件系统之后,我们还可以发现,很多文件操作并非作用于文件本身。前面已经提到,文件删除操作实际上作用于文件所属的目录文件。再比如,移动文件:

pi@raspberrypi:~/doc $ mv file.txt good/file2.txt
pi@raspberrypi:~/doc $ ls -l
总用量 4
drwxr-xr-x 2 pi pi 4096 4月  19 21:16 good
pi@raspberrypi:~/doc $ ls good/ -l
总用量 4
-rw-r--r-- 1 pi pi 31 4月  19 20:46 file2.txt
-rw-r--r-- 1 pi pi  0 4月  19 21:13 file.txt

也就是在目录文件 /home/pi/doc 中减少一个 file.txt 条目,而在 /home/pi/doc/good 中增加一个 file2.txt 的条目。整个操作过程只涉及两个目录文件。

本质上,我们对于文件本身可以进行的操作,就是读取 (Read)、写入 (Write)和运行 (Execute)。读取是从已经存在的文件中获得数据。写入是向新的文件或者旧的文件写入数据。除了读写,文件还可以作为一个程序运行。在Linux的文件系统中,如果某个用户想对某个文件执行某一种操作,那么该用户必须拥有对该文件进行这一操作的权限。Linux的文件权限与用户密切相关,后面在讲解用户时会继续深入。

6、文件搜索

Linux操作系统提供了一些用于文件搜索的命令,如find命令。 find 命令会递归地遍历文件系统,搜选出符合条件的文件。在执行find命令时,还可以说明想要对目标文件进行的操作。命令find会在找到文件后执行指定的操作。命令的基本用法:

find path ... [expression]

参数path是需要搜索的目标目录。如果有多个目标路径,则可以将多个路径依次列出。expression是一个可选的表达式,说明要对目标文件进行的操作。表达式由主操作 (Primary)和运算 (Operand)组成。

下面看一个例子,用find打印硬盘上所有文件后缀名为 .c 的文件。

pi@raspberrypi:~ $ find / -name "*.c"
/usr/lib/python2.7/config-arm-linux-gnueabihf/config.c
/usr/lib/python2.7/dist-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
/usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.c
/usr/lib/python3/dist-packages/lazy_object_proxy/cext.c
...
回显非常多,此处省略

这个命令中的表达式含有一个主操作,即-name "*.c"。该主操作会筛选文件名满足 .c 格式的文件。通配符 *** 表示任意长度的字符串。因此,“‘*.c”** 表示所有以 c 为后缀的文件。注意,Linux系统上有些文件和目录需要一定的权限才能读取,用普通权限运行上面的命令时可能会遇到权限错误。

增加否条件,打印当前目录所有后缀名不是 .c 的文件。主操作可以不止一个。当有多个主操作时,find命令会依次实现它们的功能。我们可以用-not来为筛选性操作取反,比如打印当前目录所有后缀名不是 .c 的文件:

pi@raspberrypi:~/doc $ find . -not -name ".c"
.
./good
./good/file.txt
./good/file2.txt

再比如,输出当前目录所有后缀名为 .c 文件的详细信息:

pi@raspberrypi:~/doc $ find . -not -name ".c" -ls
   521545      4 drwxr-xr-x   3 pi       pi           4096 4月 19 21:16 .
   521547      4 drwxr-xr-x   2 pi       pi           4096 4月 19 21:16 ./good
   521550      0 -rw-r--r--   1 pi       pi              0 4月 19 21:13 ./good/file.txt
   521549      4 -rw-r--r--   1 pi       pi             31 4月 19 20:46 ./good/file2.txt

命令find的用法相当繁杂,具体用例可以参考 find 的文档。相比之下,命令locate要比命令find精简很多,它也能根据文件名来寻找文件。locate也是用于查找文件的命令,与find类似,但是比find快很多,因为该命令会自动找到数据库 /var/lib/mlocate/mlocate.db 这个文件是Linux自动记录我们系统的文件,系统会定期的更新该文件。

安装locate,因为Linux没有默认安装:

pi@raspberrypi:~ $ sudo apt-get install mlocate

注意,locate命令的文件查找不是实时的,这一点和实时遍历文件树的find命令不同。文件系统的信息提前存于一个数据库,locate命令在这个数据库文件 /var/lib/mlocate/mlocate.db 中查找文件。可以用下面的命令来更新文件系统信息的数据库。

pi@raspberrypi:~ $ sudo updatedb

查找名为 grep 的文件,如下:

pi@raspberrypi:~/doc $ locate grep
/bin/bzegrep
/bin/bzfgrep
/bin/bzgrep
...
回显非常多,此处省略

本文介绍了Linux下数据存储的关键单元——文件。文件以文件树的形式组织起来,而那些用于组成文件树的目录,其实也是一种特殊的文件。最后,介绍了常用的文件搜索命令。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 xumeng32@126.com

文章标题:树莓派与Linux——Linux文件管理

文章字数:4.2k

本文作者:F_numen

发布时间:2020-04-19, 20:12:58

最后更新:2020-04-19, 22:07:20

原始链接:https://netheroone.cn/archives/9c0aa2f3.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
/*baidu统计*/