浅谈Linux下通过find命令进行rm文件删除的小技巧

我们经常会通过find命令进行批量操作,如:批量删除旧文件、批量修改、基于时间的文件统计、基于文件大小的文件统计等,在这些操作当中,由于rm删除操作会导致目录结构变化,如果要通过find结合rm的操作写成脚本,就会遇到一些麻烦,本文通过一个例子为大家进行介绍。

系统环境:

SUSE Linux Enterprise Server 11 或

Red Hat Enterprise Linux

问题症状:

客户现场有一个自动化的脚本,有以下的find语句,每天运行以删除某个目录下7天以前的文件或目录,这些目录都是按时间顺序生成PostgreSQL数据库的WAL日志及其错误日志pg_log:

/bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/rm -rf '{}' \;

运行过程中,间歇性地出现以下错误:

[root@edb ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/rm -rf {} \;
/bin/find: `/enterprisedb_backup/postgresql/network-scripts': No such file or directory
[root@edb ~]# echo $?
1

显然,以上命令返回了错误的结果,但客户反映说,以上脚本运行后目录下7天前的数据的确备删除了。

问题分析:

进行故障重现,在另一台服务器中通过模拟数据单独运行find命令分析此问题,测试过程如下:

1.模拟数据

[root@edbnode1 ~]# date
Wed Jun 18 23:08:18 CST 2014

[root@edbnode1 ~]# cp -rcp /etc/sysconfig/network-scripts/ /enterprisedb_backup/postgresql/
[root@edbnode1 ~]# cp -rcp /etc/init.d/iptables /enterprisedb_backup/postgresql/## 以上通过 cp -rcp 命令使得拷贝到目标目录的数据保持包括:建立时间、用户权根等信息,以模拟出一个旧文件及一个旧目录

[root@edbnode1 ~]# ll /enterprisedb_backup/postgresql/
total 16
-rwxr-xr-x. 1 root root 9409 Oct 31 2012 iptables
drwxr-xr-x. 2 root root 4096 Jun 18 2013 network-scripts## 以上可以看到iptables文件是2012年建立的,network-scripts是2013年建立的,都远远超过了7天

[root@edbnode1 ~]# ll /enterprisedb_backup/postgresql/*
-rwxr-xr-x. 1 root root 9409 Oct 31 2012 /enterprisedb_backup/postgresql/iptables

/enterprisedb_backup/postgresql/network-scripts:
total 212
-rw-r--r--. 1 root root  159 Jun 18 2013 ifcfg-eth0
-rw-r--r--. 1 root root  203 Jun 18 2013 ifcfg-eth1
-rw-r--r--. 1 root root  203 Jun 18 2013 ifcfg-eth2
-rw-r--r--. 1 root root  254 Jan 9 2013 ifcfg-lo
lrwxrwxrwx. 1 root root  20 Jun 18 2013 ifdown -> ../../../sbin/ifdown
-rwxr-xr-x. 1 root root  627 Jan 9 2013 ifdown-bnep
-rwxr-xr-x. 1 root root 5397 Jan 9 2013 ifdown-eth
-rwxr-xr-x. 1 root root  781 Jan 9 2013 ifdown-ippp
-rwxr-xr-x. 1 root root 4168 Jan 9 2013 ifdown-ipv6
lrwxrwxrwx. 1 root root  11 Jun 18 2013 ifdown-isdn -> ifdown-ippp
-rwxr-xr-x. 1 root root 1481 Jan 9 2013 ifdown-post
-rwxr-xr-x. 1 root root 1064 Jan 9 2013 ifdown-ppp
-rwxr-xr-x. 1 root root  835 Jan 9 2013 ifdown-routes
-rwxr-xr-x. 1 root root 1370 Jan 9 2013 ifdown-sit
-rwxr-xr-x. 1 root root 1434 Jan 9 2013 ifdown-tunnel
lrwxrwxrwx. 1 root root  18 Jun 18 2013 ifup -> ../../../sbin/ifup
-rwxr-xr-x. 1 root root 12365 Jan 9 2013 ifup-aliases
-rwxr-xr-x. 1 root root  859 Jan 9 2013 ifup-bnep
-rwxr-xr-x. 1 root root 10157 Jan 9 2013 ifup-eth
-rwxr-xr-x. 1 root root 11971 Jan 9 2013 ifup-ippp
-rwxr-xr-x. 1 root root 10401 Jan 9 2013 ifup-ipv6
lrwxrwxrwx. 1 root root   9 Jun 18 2013 ifup-isdn -> ifup-ippp
-rwxr-xr-x. 1 root root  727 Jan 9 2013 ifup-plip
-rwxr-xr-x. 1 root root  954 Jan 9 2013 ifup-plusb
-rwxr-xr-x. 1 root root 2364 Jan 9 2013 ifup-post
-rwxr-xr-x. 1 root root 4154 Jan 9 2013 ifup-ppp
-rwxr-xr-x. 1 root root 1925 Jan 9 2013 ifup-routes
-rwxr-xr-x. 1 root root 3499 Jan 9 2013 ifup-sit
-rwxr-xr-x. 1 root root 2488 Jan 9 2013 ifup-tunnel
-rwxr-xr-x. 1 root root 3770 Jan 9 2013 ifup-wireless
-rwxr-xr-x. 1 root root 4623 Jan 9 2013 init.ipv6-global
-rwxr-xr-x. 1 root root 1125 Jan 9 2013 net.hotplug
-rw-r--r--. 1 root root 13079 Jan 9 2013 network-functions
-rw-r--r--. 1 root root 29853 Jan 9 2013 network-functions-ipv6
## 以上可以看到network-script不是一个空的目录,当中还有文件,而且文件也都已经是7天前建立的了 

2.测试单独模拟执行脚本中的find + rm指令

[root@edbnode1 ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/rm -rf {} \;
/bin/find: `/enterprisedb_backup/postgresql/network-scripts': No such file or directory
[root@edbnode1 ~]# echo $?
1
[root@edbnode1 ~]# ls /enterprisedb_backup/postgresql/
[root@edbnode1 ~]#

可以看到find操作的确返回了错误的结果,但查看数据备份目录发现,iptables文件及network-scripts目录已经正确删除

3.由于数据已经正确删除,因此我们开始怀疑是由network-scripts目录删除后,find继续尝试删除此目录下其它文件,导致出不“No such file or directory”的错误,因此需要于进一步证实此猜想,重新执行以上“第1步”中的数据环境模拟,并执行以下操作,主要是将rm转换成ls以展现整体运行过程:

[root@edbnode1 ~]# cp -rcp /etc/sysconfig/network-scripts/ /enterprisedb_backup/postgresql/
[root@edbnode1 ~]# cp -rcp /etc/init.d/iptables /enterprisedb_backup/postgresql/
[root@edbnode1 ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/ls {} \;
ifcfg-eth0 ifcfg-lo	 ifdown-eth  ifdown-isdn ifdown-routes ifup		ifup-eth  ifup-isdn  ifup-post  ifup-sit	  init.ipv6-global  network-functions-ipv6
ifcfg-eth1 ifdown	 ifdown-ippp ifdown-post ifdown-sit	 ifup-aliases	ifup-ippp ifup-plip  ifup-ppp   ifup-tunnel  net.hotplug
ifcfg-eth2 ifdown-bnep ifdown-ipv6 ifdown-ppp  ifdown-tunnel ifup-bnep	ifup-ipv6 ifup-plusb ifup-routes ifup-wireless network-functions
/enterprisedb_backup/postgresql/network-scripts/ifup-plusb
/enterprisedb_backup/postgresql/network-scripts/ifup-sit
/enterprisedb_backup/postgresql/network-scripts/ifdown-post
/enterprisedb_backup/postgresql/network-scripts/ifcfg-lo
/enterprisedb_backup/postgresql/network-scripts/network-functions
/enterprisedb_backup/postgresql/network-scripts/ifup-bnep
/enterprisedb_backup/postgresql/network-scripts/ifup-ippp
/enterprisedb_backup/postgresql/network-scripts/ifdown-sit
/enterprisedb_backup/postgresql/network-scripts/ifdown-tunnel
/enterprisedb_backup/postgresql/network-scripts/ifup-plip
/enterprisedb_backup/postgresql/network-scripts/ifup-eth
/enterprisedb_backup/postgresql/network-scripts/ifdown-ipv6
/enterprisedb_backup/postgresql/network-scripts/ifdown-ippp
/enterprisedb_backup/postgresql/network-scripts/ifup-aliases
/enterprisedb_backup/postgresql/network-scripts/network-functions-ipv6
/enterprisedb_backup/postgresql/network-scripts/ifup-ipv6
/enterprisedb_backup/postgresql/network-scripts/ifup-post
/enterprisedb_backup/postgresql/network-scripts/ifcfg-eth2
/enterprisedb_backup/postgresql/network-scripts/ifcfg-eth1
/enterprisedb_backup/postgresql/network-scripts/ifdown-ppp
/enterprisedb_backup/postgresql/network-scripts/ifup-isdn
/enterprisedb_backup/postgresql/network-scripts/ifcfg-eth0
/enterprisedb_backup/postgresql/network-scripts/ifdown
/enterprisedb_backup/postgresql/network-scripts/ifup-wireless
/enterprisedb_backup/postgresql/network-scripts/ifup-ppp
/enterprisedb_backup/postgresql/network-scripts/ifdown-eth
/enterprisedb_backup/postgresql/network-scripts/init.ipv6-global
/enterprisedb_backup/postgresql/network-scripts/ifdown-isdn
/enterprisedb_backup/postgresql/network-scripts/ifup-tunnel
/enterprisedb_backup/postgresql/network-scripts/ifdown-routes
/enterprisedb_backup/postgresql/network-scripts/ifdown-bnep
/enterprisedb_backup/postgresql/network-scripts/net.hotplug
/enterprisedb_backup/postgresql/network-scripts/ifup
/enterprisedb_backup/postgresql/network-scripts/ifup-routes
/enterprisedb_backup/postgresql/iptables

通过以上操作我们可以看到,find命令不单查询了/enterprisedb_backup/postgresql/目录,并且遍历了所有子目录,因此支持了我们的推断

4.综上所述基本定位问题所在

解决方案:

1.整理思路后,可以确认,如果find只找出所需操作目录的第1层文件及目录即可解决此问题

2.通过伟大的 man 命令我们得到以下信息

-maxdepth levels
  Descend at most levels (a non-negative integer) levels of directories below the command line arguments. -maxdepth 0 means only apply the tests and actions to the command line arguments.

3.测试操作确认修改为:

[root@edbnode1 ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -maxdepth 1 -exec /bin/rm -rf {} \;
/bin/find: warning: you have specified the -maxdepth option after a non-option argument -mtime, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.

这里意思是说:-mtime找到的信息可能会操过-maxdepth的范围,在find操作中建议-maxdepth放在所有其他参数的前面

解决结果【完成】

以上这篇浅谈Linux下通过find命令进行rm文件删除的小技巧就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2016-12-05

linux find下如何统计一个目录下的文件个数以及代码总行数的命令

今天遇到如题所示问题,网上捣鼓半天,有收获 知道指定后缀名的文件总个数命令:        find . -name "*.html" | wc -l 知道一个目录下代码总行数以及单个文件行数:        find . -name "*.html" | xargs wc -l

linux find命令之xargs简单概述

在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行.但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误.错误信息通常是"参数列太长"或"参数列溢出".这就是xargs命令的用处所在,特别是与find命令一起使用. find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样.这样它可以先处理最先获取的一

linux find命令之exec简单概述

find是我们很常用的一个Linux命令,但是我们一般查找出来的并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了. exec解释: -exec 参数后面跟的是command命令,它的终止是以;为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠. {} 花括号代表前面find查找出来的文件名. 使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的.在有些操作系统中只允许-exec选

Linux中find命令的用法汇总

Linux系统中的 find 命令在查找文件时非常有用而且方便.它可以根据不同的条件来查找文件,例如权限.拥有者.修改日期/时间.文件大小等等.在这篇文章中,我们将学习如何使用 find 命令以及它所提供的选项来查找文件. 在绝大多数Linux发行版中,你都可以直接使用 find 命令而无需进行任何安装操作.如果你想在linux系统的命令行中变得特别高效,那么 find 是你必须掌握的命令之一. find 命令的基本语法如下: $ find [path] [option] [expression

linux使用find和crontab命令定期清理过期文件

crontab 命令 crontab 命令是 Linux 中用来设定重复执行命令或脚本的工具.它能够在指定的时间段内,按照需求以某一时间间隔执行命令或脚本. crontab 的基本用法 crontab [-u <user>] [-e|-l|-r] crontab <filename> crontab <filename> 可以读入一个以 crontab 语法书写的文件,并依照文件内的指示执行定时任务.与此同时,crontab -l 能够在标准输出上列出当前用户所有的定时

linux命令之find命令简单概述

Linux下find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下.即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只你具有相应的权限. 在运行一个非常消耗资源的find命令时,很多人都倾向于把它放在后台执行,因为遍历一个大的文件系统可能会花费很长的时间(这里是指30G字节以上的文件系统). 1.命令格式: find pat

Linux中find命令的用法入门

前言 Linux系统下的Find 命令具有很强大的搜索功能,可以遍历整个文件系统.所以 find 命令很耗资源,有时候甚至会耗费很长时间,因此建议把它放在后台执行. Find 命令格式如下所示: find pathname -options [-print -exec -ok -] 介绍一种简单易记的格式: find <指定目录> <指定条件> <指定动作> 动作参数 1.-exec 命令名称 {} \; 对符合条件的文件执行所给的 unix 命令,而不询问用户是否需要

Linux中 find查找命令用法详解

Linux下查找文件的命令有两个,分别是locate 和 find. locate指令和find找寻档案的功能类似,但locate是透过update程序将硬盘中的所有档案和目录资料先建立一个索引数据库,在 执行loacte时直接找该索引,查询速度会较快,索引数据库一般是由操作系统管理,但也可以直接下达update强迫系统立即修改索引数据库.简单介绍下它的两个选项. #locate -i        //查找文件的时候不区分大小写 比如:locate  –i   passwd -n      

linux的一个find命令配合rm删除某天前的文件方法

语句写法:find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 例1: 将/usr/local/backups目录下所有10天前带"."的文件删除 find /usr/local/backups -mtime +10 -name "*.*" -exec rm -rf {} \; find:linux的查找命令,用户查找指定条件的文件 /usr/local/backups:想要进行清理的任意目录 -

Windows和Linux下定时删除某天前的文件的脚本

以前做到最多的定时我们就是定时备份功能了,我们常用利用定时功能来备份网站数据或备份数据库了,下面我来给(www.jb51.net)大家介绍几个Linux与Windows中定时删除某天前的文件方法,这个与备份有点区别,但大同小义了. Windows下bat文件内容如下: 复制代码 代码如下: @echo off forfiles -p "D:\servers\apache2.2\logs" -s -m *.log -d -15 -c "cmd /c del @path"

Linux实现定时备份MySQL数据库并删除30天前的备份文件

1. MySQL5.6以上版本 2. 修改 /etc/my.cnf 文件 # vim /etc/my.cnf [client] host=localhost user=你的数据库用户 password='你的数据库密码' 3. 编写数据库脚本 mysql-backup.sh # vim mysql-backup.sh #!/bin/bash backupDir=数据库备份目录 backupTime=`date +%Y%m%d%H%M%S` mysqldump 你的数据库 | gzip > $ba

Linux下定时切割Tomcat日志并删除指定天数前的日志记录

System.out和System.err都被打印到catalina.out.catalina.out不会rotate.一般在部署Tomcat后,运行久了,catalina.out文件会越来越大,对系统的稳定造成了一定的影响. 1.可通过修改conf/logging.properties日志配置文件来屏蔽掉这部分的日志信息. [root@localhost conf]# pwd /usr/local/tomcat/conf [root@localhost conf]# cp logging.pr

python删除不需要的python文件方法

最近在看廖老师的python教程,在看到关于文件的操作时,廖老师的其中一段关于查找电脑里的python文件,突然想把之前写的python代码给删除了,因为这是第二次看教程了. import os for x in os.listdir('.'): ''' 这里的os.listdir('.')应该是定位到python所安装的目录下 ''' path = os.path.abspath('.') #把目录传给path这个变量方便在删除时能够用到os.path.join(path1, path2)把完

linux/OSX中“DD”命令制作ISO镜像操作系统安装U盘的方法

Linux或者OS X系统中,使用"dd"命令可以直接在终端命令行模式下,制作ISO镜像的系统安装盘. 一.linux系统以centOS7为例. sudo dd if=镜像路径  of=USB设备路径 bs=1m 镜像路径: ISO格式的镜像文件存放位置 USB路径: /dev/sdb  这里要注意的是: (1)USB设备不能已经挂载到其它目录,否则会提示出错.如果系统自动挂载,要先umount /dev/sdb . (2)/dev/sdb 的路径,不能带分区,例如 /dev/sdb1

用批处理文件自动备份文件及文件夹,并自动删除n天前的文件

下是备份的批处理,添加到"计划任务"中,设定时间自动运行 复制代码 代码如下: @echo off rem 格式化日期 rem date出来的日期是"2006-02-22 星期三",不能直接拿来使用,所以应该先格式化一下 rem 变成我们想要的.date:~0,4的意思是从0开始截取4个字符 set d=%date:~0,4%%date:~5,2%%date:~8,2% rem 设定压缩程序路径,这里用的是WINRAR的rar.exe进行打包的 set path=C

cmd forfiles 从文件夹或树中选择要进行批处理的文件(方便批量删除n天前的文件)

FORFILES [/P pathname] [/M searchmask] [/S] [/C command] [/D [+ | -] {yyyy-MM-dd | dd}] 描述: 选择一个文件(或一组文件)并在那个文件上 执行一个命令.这有助于批处理作业. 参数列表: /P pathname 表示开始搜索的路径.默认文件夹是当前工作的 目录 (.). /M searchmask 根据搜索掩码搜索文件.默认搜索掩码是 '*'. /S 指导 forfiles 递归到子目录.像 "DIR /S&q

使用vbs脚本定时删除N天前的文件

脚本放在定时任务里代替服务定时执行一些操作比较方便,下面是实现删除文件夹下N天前创建的文件的vbs脚本,在配置文件 DelFolderList.txt 中配置要删除的文件路径,ONLY-DEL-FILES 下的路径 是只删除其下的文件,不删除其内的子目录的文件.DEL-FOLDER-FILES下的路径 是删除其内文件及其子目录内的文件,子目录为空时删除目录,删除的文件list 放在log文件夹内.例配置文件DelFolder.txt 内容如下: ONLY-DEL-FILESE:\Code\tes