软件设计 2017-07-23
在用linux操作系统的时候,当我们忘记之前某个文件存储的位置,但是知道其文件名或者模糊的知道其文件名,我们都可以通过文件查找工具来查找,linux提供两种常用的查找工具,locate和find,在日常使用中后者比前者较前者功能更强大更具有实时性,下面我们就这两种工具来谈一谈她们的使用方法。
locate是基于实现构建好的索引库(索引库可以理解成文件路径的集合),索引库的位置放在/var/lib/mlocate/mlocate.db文件里面,系统一般一天会自动更新一次,也可以使用updatedb手动更新,要注意的是,索引库的构建过程需要遍历整个文件系统,非常消耗系统资源。
locate的特点是查找的速度快,比find快很多,因为它只在查找索引库,而find会遍历整个文件系统的路径。快的好处自然也给locate带来的缺点,就是它并非是实时查找,意思就是你如果刚刚创建了一个文件,但是你忘记了其路径,只记得其名称,那么这个时候就不建议使用locate,因为索引数据库没有更新,你使用locate查不到,除非你走运,定期更新的时间刚好在创建文件完文件之后,locate在匹配文件名的时候是模糊匹配。
下面我们就来介绍一下locate的用法:
locate
NAME:通过文件名查找文件 SYNOPSIS:locate [OPTION]... PATTERN... -b:只匹配路径中的基名; -c:输出符合条件文件的数目 -r:使用基本正则表达式 --regex:使用扩展正则表达式 -i:忽略大小写 -q:安静模式,不会有任何输出
举例1:查找含有"passwd"的文件名
[root@localhost ~]# locate passwd /etc/passwd /etc/passwd- /etc/pam.d/passwd /etc/security/opasswd /usr/bin/gpasswd /usr/bin/grub2-mkpasswd-pbkdf2 ......(省略) /usr/share/doc/passwd-0.79/AUTHORS /usr/share/doc/passwd-0.79/COPYING /usr/share/doc/passwd-0.79/ChangeLog /usr/share/doc/passwd-0.79/NEWS /usr/share/vim/vim74/ftplugin/passwd.vim /usr/share/vim/vim74/syntax/passwd.vim
我们会发现,非基名中存在passwd也会被匹配出来,我们可以使用"-b"选项来匹配:
[root@localhost ~]# locate -b passwd /etc/passwd /etc/passwd- /etc/pam.d/passwd /etc/security/opasswd /usr/bin/gpasswd /usr/bin/grub2-mkpasswd-pbkdf2 /usr/bin/kdepasswd /usr/bin/kpasswd /usr/bin/lppasswd /usr/bin/passwd /usr/bin/vncpasswd ...... /usr/share/man/zh_CN/man8/chpasswd.8.gz /usr/share/man/zh_CN/man8/smbpasswd.8.gz /usr/share/man/zh_TW/man8/chpasswd.8.gz /usr/share/ruby/webrick/httpauth/htpasswd.rb /usr/share/vim/vim74/ftplugin/passwd.vim /usr/share/vim/vim74/syntax/passwd.vim看输出的显示结果,只有基名中含有"passwd"的才会被匹配
举例2:查找只有基名中含有"passwd"的文件名的数目
[root@localhost ~]# locate -bc passwd 155
举例3:查找基名中只有"passwd"文件的文件
[root@localhost ~]# locate -br "\<passwd$" /etc/passwd /etc/pam.d/passwd /usr/bin/passwd /usr/share/bash-completion/completions/passwd
updatedb的配置文件在/etc/updatedb.conf
PRUNE_BIND_MOUNTS = "yes" PRUNEFS = "9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs coda configfs cpuset debugfs devpts ecryptfs exofs fuse fuse.sshfs fusectl gfs gfs2 gpfs hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 nfsd pipefs proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs sockfs sysfs tmpfs ubifs udf usbfs" PRUNENAMES = ".git .hg .svn" PRUNEPATHS = "/afs /media /mnt /net /sfs /tmp /udev /var/cache/ccache /var/lib/yum/yumdb /var/spool/cups /var/spool/squid /var/tmp"
PRUNE_BIND_MOUNTS:表示是否限制搜索
PRUNEFS:所列的文件系统,查找的时候不进行查找
PRUNENAMES:所列的后缀名不进行查找
PRUNEPATHS:所列的文件路径下的文件不进行查找
实时性检测
[root@localhost etc]# touch mypasswd [root@localhost etc]# [root@localhost etc]# locate mypasswd [root@localhost etc]# [root@localhost etc]# updatedb [root@localhost etc]# [root@localhost etc]# locate mypasswd /etc/mypasswd
在etc下我们创建mypasswd,立马使用locate命令查找并不能查找,使用updatedb之后更新之后索引数据库之后就可以查找到了。
通过直面意思我们就知道find就是”查找的意思,find的是一个实时查找命令,它会在查找的时候会遍历指定起始路径下文件系统层级结构完成文件查找,所以其缺点就是查找的速度要比locate慢。
下面我们就要介绍一下find的使用方法:
NAME:递归地在层次目录中处理文件 SYNOPSIS:find [OPTIONS] [查找起始路径] [查找条件] [处理动作] 查找路径:可以指定搜索目标的其实路径,默认为当前目录 查找条件:可以指定查找标准,可以根据文件名、大小、类型、从属关系、权限等匹配 处理动作:对符合查找条件的文件做出操作,比如删除等,默认行为为至标准输出
find的选项不常用,了解可使用man find来查看,下面主要来说明一下查找条件和处理动作,find的状态返回值为布尔值,查找的到则返回"0",查找不到则返回大于"0"的数字。
查找条件:
1.根据文件名查找
-name "pattern" -iname "pattern" #支持的通配符的模式,i为不区分大小写 -regex "pattern" #基于正则表达式模式查找文件,注意这里匹配的不是文件本身,而是包含这个文件路径
举例:
[root@localhost etc]# find /etc/ -name "passwd" #搜索/etc目录下含有passwd的文件 /etc/pam.d/passwd /etc/passwd [root@localhost etc]# find /etc/ -iname "passwd" #搜索/etc目录下含有passwd的文件,忽略字符大小写 /etc/pam.d/passwd /etc/passwd /etc/Passwd [root@localhost etc]# find /etc/ -iname "passwd[0-9]" #搜索/etc目录下含有passwd且后面还有0-9任意一个数字的文件 /etc/passwd1 [root@localhost etc]# find /etc/ -regex '/etc/passwd.?' #搜索/etc目录下含基名以passwd开头且后面可以有任意字符也可以没有的文件 /etc/passwd /etc/passwd- /etc/passwd1
2.根据文件从属关系查找
-user USERNAME:查找属主为指定用户的文件 -group GROUPNAME:查找属组为指定组的文件 -uid UID:查找属主为指定UID的文件 -gid GID:查找属组为指定的GID的文件 -nouser:查找没有属主的文件 -nogroup:查找没有属组的文件
举例:
[root@localhost ~]# find /tmp/ -user frank -ls #输出tmp下属主是frank的文件,-ls后面再讲 9336543 0 drwx------ 2 frank frank 27 7月 16 04:46 /tmp/kde-frank 9357728 4 -rw-rw-r-- 1 frank frank 132 7月 16 04:46 /tmp/kde-frank/xauth-1000-_0 9357736 0 drwx------ 2 frank frank 34 7月 16 04:47 /tmp/akonadi-frank.yFqCJF 9357758 0 srwxrwxr-x 1 frank frank 0 7月 16 04:46 /tmp/akonadi-frank.yFqCJF/akonadiserver.socket 27750615 0 drwx------ 2 frank frank 6 7月 16 04:47 /tmp/.esd-1000 [root@localhost ~]# find /tmp/ -group frank -ls #输出/tmp目录下属组是frank的文件 9336543 0 drwx------ 2 frank frank 27 7月 16 04:46 /tmp/kde-frank 9357728 4 -rw-rw-r-- 1 frank frank 132 7月 16 04:46 /tmp/kde-frank/xauth-1000-_0 9357736 0 drwx------ 2 frank frank 34 7月 16 04:47 /tmp/akonadi-frank.yFqCJF 9357758 0 srwxrwxr-x 1 frank frank 0 7月 16 04:46 /tmp/akonadi-frank.yFqCJF/akonadiserver.socket 27750615 0 drwx------ 2 frank frank 6 7月 16 04:47 /tmp/.esd-1000 [root@localhost ~]# find /tmp/ -uid 1000 #显示/tmp下uid为1000的文件 /tmp/kde-frank /tmp/kde-frank/xauth-1000-_0 /tmp/akonadi-frank.yFqCJF /tmp/akonadi-frank.yFqCJF/akonadiserver.socket /tmp/.esd-1000 [root@localhost ~]# find /tmp/ -nouser -ls #显示/tmp下没有属主的文件,如果一个用户创建一个文件之后,用户被删除,则显示为原来的uid和gid,不会显示属组合属主 375722 0 -rw-rw-r-- 1 1003 1003 0 7月 23 00:08 /tmp/mygrp.txt
3.根据文件类型查找
-type TYPE TYPE可以为以下: f:普通文件 d:目录文件 l:符号链接 b:块设备文件 c:字符设备文件 p:管道文件 s:套接字文件
举例:
[root@localhost ~]# find /dev/ -type b #查找dev目录下的块设备文件 /dev/dm-2 /dev/dm-1 /dev/dm-0 /dev/sr0 /dev/sda2 /dev/sda1 /dev/sda
4.根据文件大小查找
一般格式为 -size [+|-]#UNIT UNIT常用单位为:k,M,G
-size #UNIT:匹配的大小范围是#及大于#-1的文件
举例:匹配3K的大小,大于2K及小于等于3K的都会被匹配
[root@localhost ~]# ll -h 总用量 16K -rw-------. 1 root root 2.1K 7月 16 04:45 anaconda-ks.cfg -rw-r--r--. 1 root root 2.1K 7月 16 04:45 initial-setup-ks.cfg -rw-r--r--. 1 root root 555 7月 19 10:04 TEST -rw-------. 1 root root 3.0K 7月 23 00:23 test.txt [root@localhost ~]# find -size 3k -ls 27734414 4 -rw------- 1 root root 2094 7月 16 04:45 ./anaconda-ks.cfg 27734452 4 -rw-r--r-- 1 root root 2142 7月 16 04:45 ./initial-setup-ks.cfg 25795843 4 -rw------- 1 root root 3070 7月 23 00:23 ./test.txt
-size -#UNIT:匹配的范围是文件大小大于0且小于等于#-1的文件
举例:
[root@localhost ~]# find -size -3k -ls 25165889 0 dr-xr-x--- 6 root root 261 7月 23 00:23 . 27728080 4 -rw-r--r-- 1 root root 18 12月 29 2013 ./.bash_logout 27728081 4 -rw-r--r-- 1 root root 176 12月 29 2013 ./.bash_profile 27728082 4 -rw-r--r-- 1 root root 176 12月 29 2013 ./.bashrc 27728083 4 -rw-r--r-- 1 root root 100 12月 29 2013 ./.cshrc 27728084 4 -rw-r--r-- 1 root root 129 12月 29 2013 ./.tcshrc 1327848 0 drwx------ 3 root root 25 7月 16 04:45 ./.dbus 9336529 0 drwx------ 2 root root 48 7月 16 04:45 ./.dbus/session-bus 9336530 4 -rw-r--r-- 1 root root 462 7月 16 04:45 ./.dbus/session-bus/6155eeadc72c4d45b9ead1cf2a8c65a0-9 ....(省略)
-size +#UNIT:匹配的是大于#的文件
[root@localhost ~]# ll -ah 总用量 52K dr-xr-x---. 6 root root 261 7月 23 00:23 . dr-xr-xr-x. 17 root root 233 7月 16 04:44 .. -rw-------. 1 root root 2.1K 7月 16 04:45 anaconda-ks.cfg -rw-------. 1 root root 4.8K 7月 19 10:14 .bash_history -rw-r--r--. 1 root root 18 12月 29 2013 .bash_logout -rw-r--r--. 1 root root 176 12月 29 2013 .bash_profile -rw-r--r--. 1 root root 176 12月 29 2013 .bashrc drwx------. 4 root root 31 7月 16 04:46 .cache drwxr-xr-x. 3 root root 40 7月 16 04:46 .config -rw-r--r--. 1 root root 100 12月 29 2013 .cshrc drwx------. 3 root root 25 7月 16 04:45 .dbus -rw-r--r--. 1 root root 2.1K 7月 16 04:45 initial-setup-ks.cfg drwxr-xr-x. 3 root root 123 7月 16 04:45 .kde -rw-r--r--. 1 root root 129 12月 29 2013 .tcshrc -rw-r--r--. 1 root root 555 7月 19 10:04 TEST -rw-------. 1 root root 3.0K 7月 23 00:23 test.txt -rw-------. 1 root root 6.4K 7月 23 00:23 .viminfo [root@localhost ~]# find -size +3k #匹配大于3k的文件 ./.config/Trolltech.conf ./.bash_history ./.viminfo
5.根据时间戳查找
可根据天或者分钟查找
根据天: -atime n:对文件的最近一次访问是在 n*24 小时之前 -mtime n:对文件数据的最近一次修改是在 n*24 小时之前 -ctime n:对文件状态的最近一次修改是在 n*24 小时之前,当元数据修改时 根据分钟: -amin n:对文件的最近一次访问是在n分钟之前 -mmin n:对文件数据的最近一次修改是在n分钟之前 -cmin n:对文件状态的最近一次修改是在n分钟之前,当元数据修改时
同时也支持 "-atime [+|-]#"
情景1:find -atime 1 :如下图,如果现在时间是0:56分,那么查找1天前访问过的文件为哪些,查找的就是2017-7-21-0:56(不包含)到2017-7-21-00:56(包含)分访问的文件,
情景2:find -atime -1:使用"-",查找的是1天之内,如下图,如果现在是0:56,则不包括2017-7-22-0:56
情景3:find -atime +1:使用符号"+",表示的是查找1+1之前访问过的文件,如果现在0:56,则2017-7-21-00:56(包括00:56)之前访问过的文件才会被匹配
其他的ctime、mtime和分钟的查找类似,这里就不再敖述了。测试可以使用touch命令修改时间戳的方式来尝试
touch -t 201707210130 mytime.txt
6.根据权限查找
格式:-perm [/|-]mode mode:精确匹配权限 /mode:任何一类用户(u,g,o)的权限中的任何一位(r,w,x)符合条件即满足,9位权限之间存在”或关系 -mode:每一类用户(u,g,o)的权限每一位同时符合条件即满足;9位权限之间存在”与关系
举例1:精确匹配/tmp/myper目录下权限是411的文件
[root@localhost ~]# find /tmp/myper/ -perm 422 -ls 654578 0 -r---w--w- 1 root root 0 7月 23 07:32 /tmp/myper/myper2
举例2:匹配/tmp/myper其他用户有执行权限的文件
[root@localhost ~]# find /tmp/myper/ -perm /001 -ls 18772160 0 drwxr-xr-x 2 root root 62 7月 23 07:38 /tmp/myper/ 654577 0 -rw---x--x 1 root root 0 7月 23 07:32 /tmp/myper/myper1 654579 0 ---xr-xr-x 1 root root 0 7月 23 07:32 /tmp/myper/myper3 654580 0 -rwxr-xr-x 1 root root 0 7月 23 07:32 /tmp/myper/myper4
举例3:匹配/tmp/myper下user权限至少可读,group和others权限至少可以执行的文件
[root@localhost ~]# find /tmp/myper/ -perm -411 -ls 18772160 0 drwxr-xr-x 2 root root 62 7月 23 07:38 /tmp/myper/ 654577 0 -rw---x--x 1 root root 0 7月 23 07:32 /tmp/myper/myper1 654580 0 -rwxr-xr-x 1 root root 0 7月 23 07:32 /tmp/myper/myper4
处理动作:
-print:输出至标准输出,默认选项 -ls:类似对查到的文件执行"ls -l"命令 -delete:删除查到的文件 -fls /PATE/TO/SOMEFILE:把查到的所有文件的长格式信息保存至指定的文件 -ok COMMAND {} \; :对查到的每个文件执行由COMMAND表示的命令,每次操作都由用户确认 -exec COMMAND {} \; :对查到的每个文件执行由COMMAND表示的命令,无需用户确认
find传递查到的文件路径至后面的命令时,是先查找所有符合条件的路径,并一次性传递给后面的命令的,但是有些命令不能接受过长的参数,此时命令会执行失败,可以使用以下方法:
find | xargs COMMAND
xargs可以读取标准输出的内容,并以空白字元或者断行字元作为分隔符,分隔为arguments,然后一一传递给COMMAND执行
举例:查看符合条件文件的文件元数据
[root@localhost ~]# find /tmp/myper/ -perm -411 | stat stat: 缺少操作数 Try 'stat --help' for more information. [root@localhost ~]# find /tmp/myper/ -perm -411 | xargs stat 文件:"/tmp/myper/" 大小:62 块:0 IO 块:4096 目录 设备:fd00h/64768d Inode:18772160 硬链接:2 权限:(0755/drwxr-xr-x) Uid:( 0/ root) Gid:( 0/ root) 环境:unconfined_u:object_r:user_tmp_t:s0 最近访问:2017-07-23 07:38:40.570675351 +0800 最近更改:2017-07-23 07:38:33.192894947 +0800 最近改动:2017-07-23 07:38:33.192894947 +0800 创建时间:- 文件:"/tmp/myper/myper1" 大小:7 块:8 IO 块:4096 普通文件 设备:fd00h/64768d Inode:654577 硬链接:1 权限:(0611/-rw---x--x) Uid:( 0/ root) Gid:( 0/ root) 环境:unconfined_u:object_r:user_tmp_t:s0 最近访问:2017-07-23 07:58:31.699745976 +0800 最近更改:2017-07-23 07:57:38.304747287 +0800 最近改动:2017-07-23 07:57:38.304747287 +0800 创建时间:- 文件:"/tmp/myper/myper4" 大小:7 块:8 IO 块:4096 普通文件 设备:fd00h/64768d Inode:654580 硬链接:1 权限:(0755/-rwxr-xr-x) Uid:( 0/ root) Gid:( 0/ root) 环境:unconfined_u:object_r:user_tmp_t:s0 最近访问:2017-07-23 07:58:31.699745976 +0800 最近更改:2017-07-23 07:57:53.229457221 +0800 最近改动:2017-07-23 07:57:53.229457221 +0800 创建时间:-
扩展小特性:
在查找的时候多个条件之间的关系:
与:-a ,默认的关系
或:-o ,满足一个条件即可
非:-not或者! ,条件取反
有以下表达式:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
小练习:
练习1:找出/tmp目录下属主为非root的所有文件
find /tmp/ -not -user root -lsView Code
练习2:找出/tmp目录下文件名中不包含fstab字符串的文件
find /tmp/ -not -name fstabView Code
练习3:找出/tmp目录下属主为非root,而且文件名不包含fstab字符串的文件
find /tmp/ ! \( -user root -o -name fstab \)View Code
练习4:查找/var目录下属主为root,且属组为mail的所有文件或目录
find /var/ -user root -a -group mail -lsView Code
练习5:查找/usr目录下不属于用户root, bin或hadoop的所有文件或目录;用两种方法
find /usr/ -not -user root -a -not -user bin -a -not -user hadoop find /usr/ -not \( -user root -o -user bin -o -user hadoop \)View Code
练习6:查找/etc目录下最近一周内其内容修改过,且属主不是root用户也不是hadoop用户的文件或目录
find /etc/ -mtime 7 -a -not -user root -a -not -user hadoopView Code
练习7:查找当前系统上没有属或属组,且最近一周内曾被访问过的文件或目录
find / \( -nouser -o -nogroup \) -atime -7View Code
练习8:查找/etc目录下大于1M且类型为普通文件的所有文件
find /etc/ -size +1M -type f -exec ls -lh {} \;View Code
练习9:查找/etc目录下所有用户都没有写权限的文件
find /etc/ -not -perm /222View Code
练习10:查找/etc目录至少有一类用户没有执行权限的文件
find /etc/ -not -perm -111View Code
练习11:查找/etc/init.d/目录下,所有用户都有执行权限,且其它用户有写权限的所有文件
find /etc/init.d/ -perm -113View Code