本身的《Linux系统管理初学者指南--基于CentOS 7.6》已于2019年10月份出版,对于这本书的质量整体上感受还算满意,可是限于当时的知识水平,有些地方描述的仍然不是很清楚,因此在讲课的过程当中也在不断进行修订。好比最近在讲到find命令的处理动做时,很多学生就提出疑问,于是我对原书中这部份内容进行了重写,但愿再版时能够订正。linux
find命令不只能够查找,还能够对找到的结果进行进一步的处理,这就要用到“处理动做”。
例如,找出/usr/bin目录中全部的符号连接文件。[root@localhost ~]# find /usr/bin -type l
上面这条命令查找出来的结果只显示文件名,若是咱们还想查看每一个符号连接文件都指向了哪一个源文件,就能够在find命令的最后加上处理动做“-ls”。ssh
[root@localhost ~]# find /usr/bin -type l -ls 50346791 0 lrwxrwxrwx 1 root root 3 2月 14 2019 /usr/bin/captoinfo -> tic
须要注意的是,这个处理动做“-ls”属因而find命令的一部分,而并不是是以前所介绍的ls命令,于是没法在处理动做“-ls”以后加上ls命令的各类选项。例如,咱们但愿找出/etc目录中全部大小在1MB以上的文件,并人性化显示其详细信息,那么执行下面的命令就会报错。ide
[root@localhost ~]# find /etc -size +1M -ls -lh find: 未知的断言“-lh”
要实现这个需求,就要借助于find命令的另一个处理动做“-exec”。这个处理动做能够将find命令找到的结果看成文件去处理,在“-exec”的后面要跟上进一步处理所要执行的命令,另外在命令中还须要使用符号“{}”表示find命令查找到的结果,在命令的最后必须添加“ \;”表示命令结束(注意前面有个空格)。
例如,找出/etc目录中全部大小在1MB以上的文件,并人性化显示其详细信息,下面这条命令才是正确的作法。在这条命令中,ls就是以前所介绍的ls命令,咱们借助于-exec将find命令找到的结果,以文件的形式传给ls命令继续处理。测试
[root@localhost ~]# find /etc -size +1M -exec ls -lh {} \; -rw-------. 1 root root 3.8M 11月 3 2018 /etc/selinux/targeted/active/policy.kern
再好比,找出/tmp目录中全部后缀为“.txt”的文件并将其删除。[root@localhost ~]# find /tmp -name "*.txt" -exec rm -f {} \;
不少同窗在这里会疑惑,为何这里用管道符“|”(将在2.9.5节介绍)没法实现上面的操做呢?好比咱们作下面的测试:code
[root@localhost ~]# touch /tmp/{a,b,c}.txt #在/tmp目录中生成3个测试文件 [root@localhost ~]# find /tmp -name "*.txt" | rm -f #利用管道结合rm删除 [root@localhost ~]# find /tmp -name "*.txt" #测试文件仍然存在 /tmp/a.txt /tmp/b.txt /tmp/c.txt [root@localhost ~]# find /tmp -name "*.txt" -exec rm -f {} \; #利用exec结合rm删除 [root@localhost ~]# find /tmp -name "*.txt" #测试文件被成功删除
处理动做-exec最主要的做用就是能够将find命令找到的结果当成文件去处理,而默认状况下,find命令找到的结果是被看成文本信息去处理的。
怎样理解上面这段话呢?好比对于执行“find /tmp -name "*.txt"”命令所找到的三个文件:/tmp/a.txt、/tmp/b.txt、/tmp/c.txt,默认状况下find命令只是把符合查找条件的这三个文件找到,并把它们的名字在屏幕上输出,于是咱们在屏幕上所看到的只是三行文本信息。对于文本信息,可使用以前介绍的文件内容操做命令进行处理,好比用wc命令统计行数,用grep命令进行过滤等。对象
[root@localhost ~]# find /tmp -name "*.txt" | wc -l #统计find找到的文件数量 3 [root@localhost ~]# find /tmp -name "*.txt" | grep 'a' #对find的结果进行过滤 /tmp/a.txt
对于文本信息,以前介绍的文件和目录操做命令就没法处理了,好比cp、mv、rm等,由于这些命令所操做的对象必须是文件。此时-exec就能够派上用场,由于它的主要做用就是能够将find命令找到的结果再也不看做是文本信息,而是看做文件。于是若是须要对find的结果用文件操做命令进行进一步处理的话,那么就须要结合-exec。
例如,查找/boot目录下的以“init”开头的文件,并将其复制到/tmp目录。[root@localhost ~]# find /boot -name "init*" -exec cp {} /tmp \;
除了-ls和-exec以外,还有一个比较经常使用的处理动做是-delete,它能够将find找到的结果直接删除。
例如以前的操做:找出/tmp目录中全部后缀为“.txt”的文件并将其删除。其实更为简便的作法是下面的命令:[root@localhost ~]# find /tmp -name "*.txt" -delete
blog
当在find命令中利用-exec对查找到的结果进行进一步处理时,有时可能会出现问题。这是由于-exec是将find所找到的结果一次性地送给后面的命令进行处理,有时候find可能会找到大量的文件,超出了后面的命令所能处理的参数范围,这时就会出现溢出错误,错误信息一般是“参数列太长”或“参数列溢出”,这时就可使用xargs命令。xargs虽然自己是一个独立的Linux命令,但一般都是被用来配合find命令使用。经过xargs,能够将find所找到的结果分批次地送给以后的命令进行处理,从而避免出现溢出问题。
xargs命令须要经过管道与find命令配合使用,xargs的命令格式“find ……| xargs commands”。
下面咱们先准备一个测试文件。get
[root@localhost ~]# mkdir /tmp/pass [root@localhost ~]# echo "password:123" >> /tmp/pass/test.txt
假设在/tmp目录中存放了大量的文件,在其中的某个文件里存放了一个密码,关键字为“password”,咱们如今但愿可以将这个存放了密码的文件找出来。
若是利用find命令的-exec选项,能够执行下面的命令:it
[root@localhost ~]# find /tmp -type f -exec grep "password" {} \; password:123
能够发现,虽然经过上面的命令找出了密码,但并无显示存放该密码的文件名。下面换作用xargs命令来实现该要求,xargs就能够将关键字所在的文件一并显示出来。class
[root@localhost ~]# find /tmp -type f | xargs grep "password" /tmp/pass/test.txt:password:123
再好比,咱们但愿将/tmp目录以及/tmp全部下级子目录中,文件名以“.txt”做为后缀的文件都复制到/root目录中。若是用find命令的-exec来实现:[root@localhost ~]# find /tmp -name "*.txt" -exec cp {} /root \;
若是用xargs命令来实现,一样须要用“{}”来代指find命令查找到的结果,而且须要为xargs命令添加-i选项。[root@localhost ~]# find /tmp -name "*.txt" | xargs -i cp {} /root
经过这几个实例能够发现,xargs命令与find命令-exec处理动做的功能基本相同,因此若是-exec能够知足要求,那么就无需使用xargs命令。xargs命令的主要用途在于它能够对find命令找到的结果分批处理,避免出现溢出错误。
好比在/etc目录中一共有2507个普通文件。
[root@localhost ~]# find /etc -type f | wc -l 2507
若是咱们但愿能找出/etc目录中全部包含关键字“PermitRootLogin”的文件,分别用这两种方法来实现:
[root@localhost ~]# find /etc -type f -exec grep "PermitRootLogin" {} \; #PermitRootLogin yes # the setting of "PermitRootLogin without-password". [root@localhost ~]# find /etc -type f | xargs grep "PermitRootLogin" /etc/ssh/sshd_config:#PermitRootLogin yes /etc/ssh/sshd_config:# the setting of "PermitRootLogin without-password".
能够发如今用-exec的方法实现时,出现了明显的卡顿,若是数据量再大一些的话,可能就会致使溢出。而用xargs命令来实现,一方面更为快速,另外一方面不会出现溢出问题,并且显示的内容也更为详细。因此在进行这类操做时,更加推荐使用xargs命令。