Reference: 【1】 鸟哥 《鸟哥的 LINUX 私房菜》 【2】 Linux updatedb 命令.
文件的查找是极其常用的功能,因为我们常常需要知道哪个文件放在哪里,才能够对该文件进行一些修改或维护等操作。
1. 脚本文件的查找
1.1 which - 查找【执行文件】
which 命令是根据 PATH 环境变量所规范的路径,去查找执行文件的文件名。所以,重点是找出执行文件,which 后面接的是完整文件名。
语法
which [-a] command
参数
- -a: 将所有由 PATH 目录中可以找到的命令均列出,而不止第一个被找到的命令名称。
用法
# which ls # 检索 ls 命令文件,找到文件路径
/bin/ls
# which history # 检索 history 命令文件,找不到文件路径
这里需要提一下找不到 history 这个常用命令的原因 ------ 这是因为 history 是 bash 内置的命令。但是 which 默认是找 PATH 内所设置的目录,所以当然一定找不到的(有 bash 就有 history )。
2. 文件的查找
在 Linux 下有些相当优异的查找命令,通常 find 不很常用 ------ 除速度慢之外,也影响硬盘性能。一般都是先使用 whereis 或是 locate 来检查,如果真找不到了,才以 find 来查找。
为什么?因为 whereis 只找系统中某些特定目录下面的文件而已,locate 则是利用数据库来查找文件名。这两者都相当的快速,并且没有实际查找硬盘内的文件系统状态,比较省时间。
2.1 whereis - 在一些特定的目录中查找文件
一会儿会提到 find 命令,它是很强大的查找命令,但是所用时间很多(因为 find 直接查找硬盘,如果硬盘比较老旧,那么有的等)。这个时候 whereis 就相当好用了。
语法
whereis [-bmsu] 文件或目录
参数
- -l: 可以列出
whereis 会去查询的几个主要目录; - -b: 只找 binary(二进制)格式的文件;
- -m: 只找在说明文件 manual 路径下的文件;
- -s: 只找 source 源文件;
- -u: 查找不在上述三个项目当中的其他特殊文件;
用法
# whereis ifconfig # 找出 ifconfig 这个文件名
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz
## 只找出跟 passwd 有关的【说明文件】文件名(man page)
# whereis passwd # 全部的文件名通通列出来
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man5/passwd.5.gz /usr/share/man/man1/passwd.1.gz /usr/share/man/man1/passwd.1ssl.gz
# whereis -m passwd # 只有在 man 里面的文件名才显示出来
passwd: /usr/share/man/man5/passwd.5.gz /usr/share/man/man1/passwd.1.gz /usr/share/man/man1/passwd.1ssl.gz
whereis 可以加入选项来查找相关的数据。例如,如果要找的是可执行文件,那么 -b 就可以。如果不加任何选项的话,那么就将所有的数据显示出来。
为什么 whereis 的查找速度会比 find 快这么多?只是因为 whereis 只找几个特定的目录,并没有全系统去查询。
所以说,whereis 主要是针对 /bin , /sbin 下面的执行文件,以及 /usr/share/man 下面的 man page 文件,跟几个比较特定的目录来处理而已,所以速度当然快得多。
想知道 whereis 到底查了多少目录,可以使用 whereis -l 来确认。
2.2 locate / updatedb
- locate: 依据
/var/lib/mlocate 内的数据库记录,找出用户所输入关键词的文件名; - updatedb: 根据
/etc/updatedb.conf 的设置去查找系统硬盘内的文件,并更新 /var/lib/mlocate 内的数据库文件。
语法
locate [-ir] keyword
参数
- -i: 忽略大小写的差异;
- -c: 不输出文件名,仅计算找到的文件数量;
- -l: 仅输出几行的意思,例如输出五行为
-l 5 ; - -S: 输出 locate 所使用的数据库文件的相关信息,包括该数据库记录的文件/目录数量等;
- -r: 后面可接正则表达式的显示方式;
locate 用法
# locate -l 5 passwd # 找出系统中所有与 passwd 相关的文件名,且只列出 5 个。
/etc/passwd
/etc/passwd-
/etc/cron.daily/passwd
/etc/pam.d/chpasswd
/etc/pam.d/passwd
# locate -S # 列出 locate 查询所使用的数据库文件的文件名与各数据数量。
Database /var/lib/mlocate/mlocate.db:
363,255 directories
5,120,019 files
488,852,913 bytes in file names
155,776,620 bytes used to store database
locate 的使用非常简单,直接在后面输入文件的部分名称后,就能够得到结果。这是个特别方便好用的命令,尤其是在忘记某个文件的完整文件名时。
限制
但是,这个东西还是有使用上的限制。你会发现使用 locate 来寻找数据特别快,这是因为 locate 寻找的数据是由已建立的数据库 /var/lib/mlocate/ 里面的数据所查找到的,所以不用直接再去硬盘中读取数据,这样当然是很快速的。
那么有什么限制呢?就是因为它是经由数据库来查找的,而数据库的建立默认是在每天执行一次(每个 Linux 发行版都不同),所以当新建立起来的文件,却还在数据库更新之前查找该文件,那么 locate 肯定是找不到的,这时必须要更新数据库。
那能否手动更新数据库呢?当然可以,更新 locate 数据库的方法非常简单,直接输入 updatedb 就可以。updatedb 命令会去读取 /etc/updatedb.conf 这个配置文件的设置,然后再去硬盘里面进行查找文件名的操作,最后更新整个数据库文件。因为 updatedb 会去查找硬盘,所以在执行 updatedb 时,可能会等待数分钟的时间。
updatedb 用法
## 检测一个未存在的文件 runoob.txt
# locate runoob.txt # 检索 runoob.txt,没有任何输出,表示没有该文件
# touch ./runoob.txt # 添加文件 runoob.txt
# locate runoob.txt # 再次检索 runoob.txt,依然没有该文件
# updatedb # 更新 locate.db 数据库
# locate runoob.txt # 再次数据库检索 runoob.txt,找到该文件
/root/runoob/runoob.txt
2.3 find
语法
find [PATH] [option] [action]
参数1:
与文件权限及名称有关的参数:
- -name filename: 查找文件名称为 filename 的文件;
- -size [+-]SIZE: 查找比 SIZE 还要大(+)或小(-)的文件 。这个 SIZE 的规格有:
c:代表 Bytes,k:代表 1024Bytes。所以,要找比 50KB 还要大的文件,就是【-size +50k】 - -type TYPE: 查找文件的类型为 TYPE 的,类型主要有:一般正规文件(f),设备文件(b,c),目录(d),链接文件(l),socket(s),及 FIFO(p) 等属性;
- -perm mode: 查找文件权限【刚好等于】mode 的文件,这个 mode 为类似 chmod 的属性值,举例来说,
-rwsr-xr-x 的属性为 4755; - -perm -mode: 查找文件权限【必须要全部囊括 mode 的权限】的文件,举例来说,我们要查找
-rwxr--r-- ,亦即 0744 的文件,使用 -perm -0744 ,当一个文件的权限为 -rwsr-xr-x ,亦即 4755 时,也会被列出来,因为 -rwsr-xr-x 的属性已经囊括了 -rwxr--r-- 的属性了。 - -perm /mode: 查找文件权限【包含任一 mode 的权限】的文件,举例来说,我们查找
-rwxr-xr-x ,亦即 -perm /755 时,但一个文件属性为 -rw------- 也会被列出来,因为它有 -rw.... 的属性存在。
范例1:
## 找出文件名为 passwd 这个文件
# find / -name passwd
## 找出文件名包含了 passwd 这个关键字的文件
# find / -name "*passed*" # 利用这个 -name 可以查找文件名。默认是完整文件名,如果想要找关键字,可以使用类似*的任意字符来处理
## 找出 /run 目录下,文件类型为 socket 的文件名有哪些?
# find /run -type s # 这个 -type 的属性也很有帮助,尤其是要找出那些怪异的文件。例如socket与FIFO文件,可以用 find /run -type p 或 -type 是来找
## 查找文件当中含有 SGID、SUID 或 SBIT 的属性
# find / -perm /7000 # 所谓的 7000 就是---s--s--t,那么只要含有s或t的就列出,所以当然要使用/7000,使用-7000表示要同时含有---s--s--t的所有三个选项,如果只需要任意一个,那就是/7000
参数2:
与时间有关的选项,共有-atime(读取时间)、-ctime(状态时间) 与 -mtime(修改时间),以 -mtime 说明:
- -mtime n: n 为数字,意义为在 n 天之前的【一天之内】被修改过内容的文件;
- -mtime +n: 列出在 n 天之前(不含 n 天本身)被修改过内容的文件;
- -mtime -n: 列出在 n 天之内(含 n 天本身)被修改过内容的文件;
- -newer file: file 为一个存在的文件,列出比 file 还要新的文件。
范例2:
## 将过去系统上面 24 小时内有修改过内容(mtime)的文件列出
# find / -mtime 0 # 这里 0 是重点,0 代表目前的时间,所以,从现在开始到 24 小时前,有变动过内容的文件都会被显示。那如果是三天前哪一天的24小时内,使用 find / -mtime 3
## 寻找/etc下面的文件,如果文件日期比/etc/passwd新就列出
# find /etc -newer /etc/passed # -newer 用在辨别两个文件之间的新旧关心是很有用的
|