王继敏
【摘 要】Linux下的文件查找是Linux系统运维工作的一项基本技能,Linux系统提供了一些功能强大且用法灵活的文件查找类命令。本文对Linux下的文件查找类命令进行归纳总结,以供Linux系统运维学员参考。
【关键字】文件查找;Linux
中图分类号: TP3169文献标识码: A 文章编号: 2095-2457(2019)33-0097-002
DOI:10.19694/j.cnki.issn2095-2457.2019.33.048
0 引言
在Linux下进行系统管理时,对于文件系统内所需要查找的文件进行快速并有效的定位是一项必备的基本技能。Linux系统提供了一些功能强大且用法灵活的文件查找类命令,以下是笔者在Linux系统运维教学培训工作中总结出来的作为Linux下的一名运维工程师应该熟练掌握的文件查找类命令用法。
1 which
命令which是一个相对功能比较简单的文件查找命令,which命令后面跟上一个命令名,它可以查看某个系统命令是否存在,以及执行的到底是哪一个位置的命令。命令which的执行方式是在PATH变量指定的路径中进行搜索,并且返回第一个搜索结果。如查看系统是否安装了g++编译器以及g++编译器的安装位置,执行以下命令系统返回如下结果:
#which g++
/usr/bin/g++
2 whereis
命令whereis可以用来查找一个外部命令的二进制文件、源代码文件及用户手册文档。如用whereis命令查找g++,除了找到g++命令对应的二进制文件外,还找到了g++命令的用户文档:
#whereis g++
g++:/usr/bin/g++ /usr/share/man/man1/g++.1.gz
3 locate
上述的which和whereis两条命令,对于查找非系统命令以外的其他文件,如用户的如个人文档、视频照片、mp3音乐等等是无能为力的,它们仅能用于查找安装到系统内的外部命令所对应的文件。而命令locate则没有这一限制,如查找用户家目录下的RHEL6.3光盘镜像文件:
$ locate rhel-server-6.3-x86_64-dvd.iso
命令locate是从文件系统内已存在的一个文件信息数据库中进行查找(在RHEL6.3中,这个文件信息数据库是/var/lib/mlocate/mlocate.db),而不是对整个文件系统进行遍历,因此locate命令的查询速度比起find命令来快得多。在RHEL6.3中,每日定时更新这个数据库已经被创建在了默认的计划任务中了。但是如果是用户刚创建好的文件,因为此文件信息数据库还没有更新,这个文件还没有被添加到文件信息数据库中,因此用locate命令是查找不到的。如让一个普通用户在其家目录下创建一个myNewFile文件,然后用locate命令去查找,可以通过终端键入以下命令:
$touch ~/myNewFile
$locate myNewFile
此时因为文件信息数据库还没有更新,因此查找失败。此时如果想立即手动更新该文件信息数据库,需要以管理员身份执行updatedb命令,然后locate命令可以找到该文件了。例如接着在终端执行以下命令,则刚才新建立的myNewFile文件便可以找到了:
$sudo updatedb
$locate myNewFile
/home/wjm/myNewFile
4 find
命令find是Linux中一个使用频繁且功能十分强大的文件查找命令。与locate命令不同,find命令不查询文件信息数据库,而是实时的遍历整个文件系统目录树,因此find查找文件的速度是比较慢的。命令find可以设置多种搜索条件,可以查找各种类型的文件,使用方法十分灵活。在man手册页中描述find命令的语法格式为:
find[-H][-L][-P][-D debugopts][-Olevel][path…] [expression]
其中-H、-L和-P三个选项用来控制对于符号链接的处理,其实并不常用,具体用法可以参阅man手册,此处不再赘述。选项path规定find命令所查找的目录路径。例如用~来表示从用户的家目录开始查找,用/tmp来表示查找/tmp目录下的文件,如果是从当前目录开始查找,则path可以省略。选项expression可以分解为——“-options [-print -exec -ok …]”,以下对这几个子选项进行解释:
-options,find命令的常用选项,一般为指定查找条件,下面举例介绍。
-print,将匹配的文件输出到标准输出。
-exec,对匹配的文件执行该参数所给出的shell命令。相应命令的形式为command{ }\;,注意{ }和\;之间的空格。
-ok,和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
其实find用户手册给出的语法描述十分烦琐且不容易記忆,实际使用中可以将find命令的用法简单归纳为“find [目录] [条件] [动作]”,其中[目录]规定查找的起始目录,[条件]指定查找的条件,[动作]规定对于找到的文件执行什么样的操作,如删除、重命名等等。
下面的几个例子演示了在实际操作中常见的用find命令查找文件的用法:
(1)-name 按文件名查找
例如以/var为起始目录,查找所有文件名以“.log”为后缀的日志文件:
# find /var -name *.log
(2)-user & -group 按文件的属主或属组查找
如在系统根目录下查找用户属主为wjm且用户属组为wjm的文件,用如下命令:
# find / -user wjm && -group wjm
(3)-type 查找某一类型的文件
Linux下有多种文件类型,在find命令中,可以指定要查找的文件类型,如:
如在系统根目录下查找用户属主为wjm且用户属组为wjm的普通文件(不包括目录),可以用如下命令:
# find / -type f -user wjm && -group wjm
(4)-size 按照文件的大小来查找
-size后面跟上一个数字指定要查找的文件大小,默认的单位是字节。还可以在数字后面跟一个表示大小的单位,如k、M或者G分别表示KB、MB和GB。如果在数字前面加上一个-或者+号,则分别表示小于或者大于。例如查找/var目录下零字节大小的文件,并用长格式列出文件的详细信息:
# find /var -size 0 -exec ls -l {} \;
(5)-mtime & -ctime & -atime 按时间来查找
在Linux系统中,每个文件均有三个时间戳,即mtime、ctime和atime。其中mtime为文件的修改时间,即文件内容被修改的时间;mtime为文件的改变时间,即文件属性(如属主、属组等)被改变的时间;ctime为文件的访问时间,即文件上一次被访问的时间。命令find可以针对这三个时间进行查找。如果在该选项后面跟数字“N”,则表示条件为该时间戳距离今天恰好N天;如果在该选项后面跟数字“+N” 则表示条件为该时间戳距离今天超过N天;如果在该选项后面跟数字“-N”,则表示条件为该时间戳距离今天不到N天。
例如用find命令在系统/tmp目录下查找文件,如果该文件在7日内没有被访问过则将其删除,并将其删除:
$ find /tmp -atime +7 -exec rm {} \;
(6)-perm 按照文件的权限来查找
Linux系统中的每个文件有读、写和执行三种权限,并且还有三种特殊权限SUID、SGID和Sticky Bit,因此每个Linux系统中的文件可以用一个四位十六进制数字来表示。可以用-perm 按照文件的权限来查找,例如查找系统中所有具有SUID权限的文件,并用长格式列出其详细信息:
# find/-perm -4000 -exec ls -l {} 2> /dev/null \;
(7)find命令和其他命令結合使用
命令find在众多Linux命令中使用十分灵活,它经常和其他命令结合在一起使用。例如下面这条命令将用户家目录下所有文件名以.sh为后缀的普通文件中的字符串"boy"替换为"girl":
$ find ~ -type f -name "*.sh" | xargs sed -i "s#boy#girl#g"
例如下面这则shell脚本程序使用find命令查找系统中所有设置了ACL权限的文件:
#!/bin/bash
for file in `find / \( -path "/sys" -o -path "/proc" \) -prune -o \( -type f -o -type d \) -print`
do
num=`getfacl $file 2> /dev/null | grep "mask:" | wc -l`
if [ $num -gt 0 ]; then
echo $file
fi
done
5 结束语
前面列举的which、whereis、locate和find命令是Linux运维工程师应该熟练掌握的文件查找类命令。笔者在文中仅仅列举了一些常见用法,更加灵活的使用还需要在工作中慢慢积累和摸索。
【参考文献】
[1]鸟哥.鸟哥的Linux私房菜基础学习篇[M].第三版.北京:人民邮电出版社,2010.