find命令详解
前言
find命令的格式是什么?
参数中出现+或-号是什么意思?比如find / -mtime +7与find / -mtime -7什么区别?
find /etc/ -name “passwd” -exec echo {} \;和find /etc/ -name “passwd” -exec echo {} +有啥区别?
-exec参数为什么要以“\;”结尾,而不是只写“;”?
命令基础
find /etc -name 'passwd'
find /etc /var /usr -name 'passwd'
find命令中的表达式有四种类型,分别是:
Tests:就是我们最常用的指定查找文件的条件。
Actions:对找到的文件可以做的操作。
Global options:全局属性用来限制一些查找的条件,比如常见的目录层次深度的限制。
Positional options:位置属性用来指定一些查找的位置条件。
TESTS
+n:表示大于n。
-n:表示小于n。
n:表示等于n。
根据时间查找
[root@zorrozou-pc0 zorro]# find / -mtime 7 -ls
[root@zorrozou-pc0 zorro]# find / -mtime 7 -ls|head
524295 4 drwxr-xr-x 12 root root 4096 6月 8 13:43 /root/.config
524423 4 drwxr-xr-x 2 root root 4096 6月 8 13:43 /root/.config/yelp
524299 4 drwxr-xr-x 2 root root 4096 6月 8 13:23 /root/.config/dconf
524427 4 -rw-r--r-- 1 root root 3040 6月 8 13:23 /root/.config/dconf/user
...
我们会发现,时间都集中在6月8号,而今天是:
[root@zorrozou-pc0 zorro]# date
2016年 06月 15日 星期三 14:30:09 CST
[root@zorrozou-pc0 zorro]# find / -mtime 7 -exec ls -tld {} \+
[root@zorrozou-pc0 zorro]# find / -mtime -7 -exec ls -tld {} \+
[root@zorrozou-pc0 zorro]# find /etc -anewer /etc/passwd
[root@zorrozou-pc0 zorro]# find /etc/ -newermc /etc/passwd
c:文件change time。
m:文件modify time。
根据用户查找
-uid n:文件的所属用户uid为n。
-user name:文件的所属用户为name。
-gid n:文件的所属组gid为n。
-group name:所属组为name的文件。
-nogroup:没有所属组的文件。
-nouser:没有所属用户的文件。
根据权限查找
[root@zorrozou-pc0 zorro]# find /etc/ -perm 644 -ls
这个写法跟:
[root@zorrozou-pc0 zorro]# find /etc/ -perm u=rw,g=r,o=r -ls
是等效的。
另外要注意,mode指定的是完全符合这个权限的文件,如:
[root@zorrozou-pc0 zorro]# find /etc/ -perm u=rw,g=r -ls
263562 4 -rw-r----- 1 root brlapi 33 11月 13 2015 /etc/brlapi.key
[root@zorrozou-pc0 zorro]# find /etc/ -perm 600 -ls
根据路径查找
-name pattern:文件名为pattern指定字符串的文件。注意如果pattern中包括*等特殊符号的时候,需要加””。
-iname:name的忽略大小写版本。
-lname pattern:查找符号连接文件名为pattern的文件。
-ilname:lname的忽略大小写版本。
-path pattern:根据完整路径查找文件名为pattern的文件,如:
[root@zorrozou-pc0 zorro]# find /etc -path '/e*d'| head
/etc/machine-id
/etc/profile.d
/etc/vnc/xstartup.old
/etc/vnc/config.d
/etc/vnc/updateid
/etc/.updated
-ipath:path的忽略大小写版本。
-regex pattern:用正则表达式匹配文件名。
-iregex:regex的忽略大小写版本。
其他状态查找
-empty:文件为空而且是一个普通文件或者目录。
-size n[cwbkMG]:指定文件长度查找文件。单位选择位:
c:字节单位。
b:块为单位,块大小为512字节,这个是默认单位。
w:以words为单位,words表示两个字节。
k:以1024字节为单位。
M:以1048576字节为单位。
G:以1073741824字节温单位。
n的数字指定也可以使用+-号作为前缀。意义跟时间类似,表示找到小于(-)指定长度的文件或者大于(+)指定长度的文件。
-inum:根据文件的inode编号查找。
-links n:根据文件连接数查找。
-samefile name:找到跟name指定的文件完全一样的文件,就是说两个文件是硬连接关系。
-type c:以文件类型查找文件:
c可以选择的类型为:
b:块设备
c:字符设备
d:目录
p:命名管道
f:普通文件
l:符号连接
s:socket
ACTIONS
-fls file:跟-ls功能一样,区别是将信息写入file指定的文件,而不是显示在屏幕上。
-print:将找到的文件显示在屏幕上,实际上默认find命令就会将文件打印出来显示。
-print0:-print参数会将每个文件用换行分割,而这个参数适用null分割。有时候在脚本编程时可能会用上。
-fprint file:-print参数的写入文件版本。将内容写到文件中,而不是显示在屏幕上。
-fprint0 file:-print0的写入文件版本。
-delete:可以将找到的文件直接删除。
-printf:格式化输出方式打印。如:
[root@zorrozou-pc0 zorro]# find /etc/ -name 'pass*' -printf '%p '
/etc/default/passwd /etc/pam.d/passwd /etc/passwd- /etc/passwd
显示文件名,并以空格分隔。%p代表文件名。其他信息可以参见man find。
-prune:如果复合条件的是一个目录,则不进入目录进行查找。例子:
[root@zorrozou-pc0 zorro]# mkdir /etc/passs
[root@zorrozou-pc0 zorro]# touch /etc/passs/passwd
[root@zorrozou-pc0 zorro]# find /etc/ -name 'pass*' -prune
/etc/passs
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
[root@zorrozou-pc0 zorro]# find /etc/ -name 'pass*'
/etc/passs
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
-quit:找到符合条件的文件后立即退出。
find中执行命令
-exec
find命令的exec是一个非常好用的参数,当然其可能造成的破坏也可能非常大。在学习它之前,我先要提醒大家,使用之前千万要确定自己在做什么。
这个参数的常见格式是:
-exec command ;
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -exec echo {} \;
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd
上面的命令表示,找到/etc/目录下文件名为passwd的文件,并echo其文件名。注意再使用分号的时候前面要加转移字符\,因为分号也是bash的特殊字符,所以bash会先解释它。前面加上\就可以让bash直接将其船体给find命令,这个分号由find解释,而不是bash。其实这个exec用的比较废话,毕竟find本身就会找到相关条件的文件并显示其文件名。但是试想如果我们将echo换成rm或者cp,是不是就有意义的多?比如:
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -exec rm {} \;
请不要执行这个命令!!
或者:
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -exec cp {} {}.bak \;
这个命令可以将符合条件的文件都加个.bak后缀备份一份。于是我们可以执行删除了:
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd.bak'
/etc/default/passwd.bak
/etc/pam.d/passwd.bak
/etc/passwd.bak
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd.bak' -exec rm {} \;
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd.bak'
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -exec echo {} \;
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -execdir echo {} \;
./passwd
./passwd
./passwd
一个命令打印出来的路径都是/etc/开头,另一个显示的都是当前目录下的某某文件。
execdir的方式要比exec安全一些,因为这种执行方式避免了在解析文件名时所产生的竞争条件。
出了上述两种比较典型的执行命令的方法以外,find还对这两个参数提供了另一种形式的命令执行格式:
-exec command {} +
-execdir command {} +
我们还是先用例子来看一下这个格式和以分号结束的方式的差别:
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -exec echo {} \;
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd
[root@zorrozou-pc0 find]# find /etc/ -name 'passwd' -exec echo {} \+
/etc/default/passwd /etc/pam.d/passwd /etc/passwd
光这样看可能还不是很明显,我们可以这样在描述一遍他们的执行过程:
echo /etc/default/passwd
echo /etc/pam.d/passwd
echo /etc/passwd
和
echo /etc/default/passwd /etc/pam.d/passwd /etc/passwd
[root@zorrozou-pc0 find]# find /etc -mtime -7 -type f -exec cp -t /tmp/back/ {} \+
find /etc -mtime -7 -type f -exec cp {} /tmp/back/ \+
[root@zorrozou-pc0 find]# find /etc -mtime -7 -type f -ok cp -t /tmp/back/ {} \;
< cp ... /etc/bluetooth/main.conf > ?
OPERATORS
[root@zorrozou-pc0 zorro]# find /etc -name 'pass*' -type f
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
[root@zorrozou-pc0 zorro]# find /etc -name 'pass*' -a -type f
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
[root@zorrozou-pc0 zorro]# find /etc -name 'pass*' -and -type f
/etc/passs/passwd
/etc/default/passwd
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
除了逻辑与关系以外,还有逻辑或关系:
[root@zorrozou-pc0 zorro]# find /etc -name 'pass*' -o -type f
[root@zorrozou-pc0 zorro]# find /etc -name 'pass*' -or -type f
[root@zorrozou-pc0 zorro]# find / \( -name 'passwd' -a -type f \) -o \( -name 'shadow' -a -type f \)
最后
来源:Linux系统技术
(版权归原作者所有,侵删)
微信扫码关注该文公众号作者