星期五, 二月 09, 2007

find -path dir/* -prune

有时候,备份时可能只希望删除某个目录下的文件和子目录,但需要保留目录本身。因为 fs_backup 是利用 find 来查找文件的,所以如果 find 本身可以解决这个问题,就不需要在另外编码了。幸运的是,find 可以:
sh$ find . -path ./linux-2.6.16.28 -prune -o -print | grep linux-2.6.16.28
./linux-2.6.16.28.SMP
./linux-2.6.16.28.tar.bz2
sh$ find . -path ./linux-2.6.16.28/* -prune -o -print | grep linux-2.6.16.28
find: paths must precede expression
Usage: find [path...] [expression]
sh$ find . -path './linux-2.6.16.28/*' -prune -o -print | grep linux-2.6.16.28
./linux-2.6.16.28
./linux-2.6.16.28.SMP
./linux-2.6.16.28.tar.bz2
这样,在使用 fs_backup 时就可以使用如下方式来加入或排除一个目录是否被备份:
sh$ fs_backup -a t:/path/to/dir/*
sh$ fs_backup -a x:/path/to/dir/*
只是 fs_backup 这个脚本调用 os.popen3(command) 时这个 command(即 find 的命令)需要做出调整,在代码生成时给 -path 'dir/*' 加上引号。

另外,再更进一步看看 find -path dir/*/* 是否可以呢?
sh$ find . | grep subversion
./.subversion
./.subversion/README.txt
./.subversion/config
./.subversion/servers
./.subversion/auth
./.subversion/auth/svn.username
./.subversion/auth/svn.simple
./.subversion/auth/svn.ssl.server
sh$ find . -path ./.subversion -prune -o -print | grep subversion
sh$ find . -path './.subversion/*' -prune -o -print | grep subversion
./.subversion
sh$ find . -path './.subversion/*/*' -prune -o -print | grep subversion
./.subversion
./.subversion/README.txt
./.subversion/config
./.subversion/servers
./.subversion/auth
OK,也可以!

但看一下实际的执行情况:
sh# cat /var/fs_backup/myopt/.t_files
/opt
sh# cat /var/fs_backup/myopt/.x_files
/opt/backup
/opt/profiles/*
sh# ./fs_backup myopt
/opt/profiles/* is not a valid file or directory
find /opt \( -path '/opt/backup' \) -prune ! -type d -print >>/tmp/fs_backup.myopt.full.1171197285.0.list
这是因为在寻找顶级文件/目录列表时的问题,因为 * 通配符不被支持。修改如下:
 83 def find_top_files(tmpl):
84 import glob
85 tmpl.sort()
86 topfiles = []
87 invalids = []
88 file1 = ''
89 for item in tmpl:
90 item = item.strip()
91 if not os.path.exists(item) and len(glob.glob(item)) == 1:
92 # There may be 'dir/*' style string
93 strerr = "^[[31m%s is not a valid file or directory^[[00m" % item
94 print >> sys.stderr, strerr
95 invalids.append(item)
96 continue
97 if not file1:
98 if item == '': continue #^W
99 file1 = item
100 topfiles.append(file1)
101 elif item.startswith(file1):
102 # 'file1' is the parent directory of 'item'
103 continue
104 elif file1.startswith(item):
105 file1 = item
106 topfiles[-1] = file1
107 else:
108 file1 = item
109 topfiles.append(file1)
110 return topfiles, invalids

没有评论: