已索引
which
在PATH环境变量列出的路径中搜过指定命令所在的全路径,只能精确匹配。
whereis
给出指定关键字所在的命令路径、相关的配置文件和man page
# whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
# whereis fstab
fstab: /etc/fstab /usr/include/fstab.h /usr/share/man/man5/fstab.5.gz
locate
基于/var/lib/mlocate/mlocate.db数据库查找,支持部分匹配和精确匹配。
查找会列出所有含有指定关键字的文件路径,例如:locate keyword,会发现,该查找会把系统中所有包含keyword的文件路径列出来,包括隐藏文件。
现在我们关心passwd文件,于是执行locate passwd,发现路径中包含passwd的所有文件都列出来了,但我们只关心精确的passwd文件,并不关心类似vncpasswd的文件,则可以使用方法:locate -b 'passwd'。
现在新建一个/home/some-username/newfile文件,再次运行locate newfile,发现不能找到新建的文件,这是因为locate命令是基于前面提到的数据库文件的,该数据库文件并非实时更新,而是每天凌晨去执行/etc/cron.daily/mlocate脚本更新。也可以手动直接运行updatedb 命令立即更新数据库,更新后即可找到该文件。
再建立一个/tmp/locate.file文件,更新数据库后,发现仍然找不到usr建立的文件,查看updatedb命令的man page,发现其有个配置文件/etc/updatedb.conf,里面有个PRUNEPATHS配置选项包含了/tmp/目录,继续查看 man 5 updatedb.conf,发现PRUNEPATHS参数定义的是updatedb命令要跳过的目录,去掉/tmp目录后,再次执行updatedb后,文件就能找到了。
虽然是查的索引,但locate不同于windows下的everything工具,它是安全的,用户看不到不该看到的文件。
另外,locate对于已经建立索引的文件是及时跟踪的,例如,删除文件后,locate就没有该文件了,移动文件后,locate就发现文件的路径发生变化了(RHEL6是这样,RHEL7也需要updatedb才能生效)。
find
find命令是一个非常强大和复杂的命令,更多信息可以看其 man page。
语法:find <目录> <选项> <条件> <动作>
默认目录是当前目录
默认动作是输出找到文件
查找条件可以查看man page的TEST段
小技巧:直接执行find命令会列出当前目录及其子目录下的所有文件。
按文件名查找
find /etc/ -name passwd 区分大小写
find /etc/ -iname passwd 不区分大小写
按大小查找
find / -size +20M 查找大于20M的文件
按修改时间查找(mmin和mtime):
-mmin n File's data was last modified n minutes ago.
-mtime n File’s data was last modified n*24 hours ago.
如何理解呢:
-mmin +5 5分钟前修改过的
-mmin 5 第5分钟修改过的
-mmin -5 最近5分钟内修改过的
-mtime +7 7天前修改过的
-mtime 7 第7天修改过的
-mtime -7 最近7天内修改过的
在3月4号上午执行的删除命令:
# find /orabak/zabbix_mysqldb_infras/* -mtime 1 -name "*.sql.zip" -exec rm -f {} \;
-rw-r--r-- 1 cyuser cyuser 708120517 Feb 27 01:07 zabbix_mysql_bak_240226-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 715245929 Feb 28 01:08 zabbix_mysql_bak_240227-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 722600686 Feb 29 01:09 zabbix_mysql_bak_240228-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 730037133 Mar 1 01:10 zabbix_mysql_bak_240229-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 738222877 Mar 2 01:11 zabbix_mysql_bak_240301-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 753614653 Mar 4 01:13 zabbix_mysql_bak_240303-235501.sql.zip
# find /orabak/zabbix_mysqldb_infras/* -mtime 3 -name "*.sql.zip" -exec rm -f {} \;
-rw-r--r-- 1 cyuser cyuser 708120517 Feb 27 01:07 zabbix_mysql_bak_240226-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 715245929 Feb 28 01:08 zabbix_mysql_bak_240227-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 722600686 Feb 29 01:09 zabbix_mysql_bak_240228-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 738222877 Mar 2 01:11 zabbix_mysql_bak_240301-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 753614653 Mar 4 01:13 zabbix_mysql_bak_240303-235501.sql.zip
# find /orabak/zabbix_mysqldb_infras/* -mtime +5 -name "*.sql.zip" -exec rm -f {} \;
[root@sysmon01 zabbix_mysqldb_infras]# ll /orabak/zabbix_mysqldb_infras/
total 2861044
-rw-r--r-- 1 cyuser cyuser 715245929 Feb 28 01:08 zabbix_mysql_bak_240227-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 722600686 Feb 29 01:09 zabbix_mysql_bak_240228-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 738222877 Mar 2 01:11 zabbix_mysql_bak_240301-235501.sql.zip
-rw-r--r-- 1 cyuser cyuser 753614653 Mar 4 01:13 zabbix_mysql_bak_240303-235501.sql.zip
# find /orabak/zabbix_mysqldb_infras/* -mtime -5 -name "*.sql.zip" -exec rm -f {} \;
[root@sysmon01 zabbix_mysqldb_infras]# ll /orabak/zabbix_mysqldb_infras/
total 698488
-rw-r--r-- 1 cyuser cyuser 715245929 Feb 28 01:08 zabbix_mysql_bak_240227-235501.sql.zip
多条件联合
多个条件可以同时使用,用空格隔开,此时,它们之间的关系是AND,例如:
find / -size -20M -size +10M
find / -name passwd -type d 查找名为passwd的目录(不要文件)
也可以使用OR关系:
# find /etc -name "fstab" -o -name "passwd"
-o等价于-or,还可以使用()、-not、-and、-or和 ,(看man page的OPERATORS段)
对于在shell中有特殊含义的符号,例如(),需要进行转义
find files that either start with an underscore or are newer than the file while2, but must in either case be regular files.
例如:
# find / \( -name "_*" -or -newer while2 \) -type f -print
排除某些目录进行查找
排除某个目录进行查找:
# find /tmp -path /tmp/dir2 -prune -o -name passwd -print
注意要写-print动作,如果不写,虽然不会把/tmp/dir2/passwd列出来,但会把/tmp/dir2列出来
排除多个目录进行查找:
# find /tmp \( -path /tmp/dir2 -o -path /tmp/dir3 \) -prune -o -name file -print
指定动作
find的默认动作是print,例如:
# find /root -mmin -30 –print
它还支持很多其它的动作,可以查看man page的ACTIONS字段,例如-ls:
# find /root -mmin -30 –ls
除了自带的动作指令,find还可以与其它命令配合使用:
例1:使用-exec选项配合其它命令
find / -user tom -exec cp -a {} /tmp/dir1 ;
例2:通过反引号配合其它命令使用
mv find /root/ -name "*umaks*"
/tmp/
例3:通过管道与xargs配合使用
xargs的作用是将多行内容变成一行,例如:
# cat test.txt
1 2 3 4 5 6
7 8 9
10 11
# xargs < test.txt
1 2 3 4 5 6 7 8 9 10 11
# xargs -n 4 < test.txt
1 2 3 4
5 6 7 8
9 10 11
-n的含义是每4个一行
# find /tmp -name "*umaks*"
# find /tmp -name "*umaks*" | xargs
# find /tmp -name "*umaks*" | xargs rm –rf
# find . -type f -name "file2.txt" | xargs -i mv {} /tmp/ 这儿要加上-i参数才可以使用这种语法
find试题
面试题1:删除一个目录下的所有文件,但保留一个指定文件
假设这个目录是/xx/,里面有file1,file2,file3..file10十个文件
方法1:find
find /xx -type f ! -name "file10"|xargs rm -f
find /xx -type f ! -name "file10" -exec rm -f {} ;
方法2:rsync
rsync -az --delete --exclude "file10" /null/ /xx/
面试题2:查找所有失效的符号链接
find / -path /proc -prune -o -exec file {} ; 2> /dev/null | grep 'broken symbolic link to'
面试题3:已知apache服务的访问日志按天记录在服务器本地目录/app/logs下,由于磁盘空间紧张,现在要求只能保留最近7天访问日志!请问如何解决?
两种方法:一是从apache服务配置上着手,二是通过find找到7天前的日志,删除。
使用通配符的注意事项
关于通配符,我们来看一个重要的现象
# cd
# touch /home/test.exe /root/temp.exe
# updatedb
# locate *.exe
/root/temp.exe
# locate "*.exe"
/home/test.exe
/root/temp.exe
[root@xuwang /]# cd /
[root@xuwang /]# locate *.exe
/home/test.exe
/root/temp.exe
为什么会出现这样的现象?执行ls *.exe将得到temp.exe,故locate *.exe相当于执行的是locate temp.exe,那为什么在 / 下不加” ”也能执行成功?那是因为 / 下ls *.exe没有文件。
除了使用双引号,也可以使用单引号。
同理,find等工具使用通配符时也最好加上引号。
但也不尽然,再来看一个例子:
我们希望使用watch来监控当前目录下以ip.开始的文件:
watch ls -l ip.* 和 watch ls -l ip.\*(或者watch ls -l "ip.*")
前者会对*进行通配,watch实际上监控的命令是 ls -l ip.txt ip.exe ……
后者不会对*进行通配,watch实际上监控的命令是 ls -l ip.*