如何使用 FIND 递归备份多个颠覆存储库
Posted
技术标签:
【中文标题】如何使用 FIND 递归备份多个颠覆存储库【英文标题】:How can I use FIND to recursively backup multiple subversion repositories 【发布时间】:2009-10-23 11:43:43 【问题描述】:目前,我们的备份脚本每晚都会在我们的每个存储库上明确运行 svnadmin hotcopy。我们的存储库都存储在父目录下(/usr/local/svn/repos) 我们的备份脚本对该目录下的每个存储库都有一行,如下所示: svnadmin hotcopy /usr/local/svn/repos/myrepo1 /usr/local/backup/myrepo1
我希望使用 find 命令为它在 /usr/local/svn/repos 下找到的每个目录运行 svnadmin hotcopy,而不是手动为每个新的 repo 添加一个新行。
到目前为止,我得到了:
find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup \;
,为了简单起见,我将“svnadmin hotcopy”替换为“echo”。 其输出为:
/usr/local/backup/usr/local/svn/repos/ure
/usr/local/backup/usr/local/svn/repos/cheetah
/usr/local/backup/usr/local/svn/repos/casemgt
/usr/local/backup/usr/local/svn/repos/royalliver
/usr/local/backup/usr/local/svn/repos/ure_andras
/usr/local/backup/usr/local/svn/repos/profserv
/usr/local/backup/usr/local/svn/repos/frontoffice
/usr/local/backup/usr/local/svn/repos/ure.orig
/usr/local/backup/usr/local/svn/repos/projectcommon
/usr/local/backup/usr/local/svn/repos/playground
/usr/local/backup/usr/local/svn/repos/casegen
完整路径的问题包含在 中。我只需要传递给 -exec 的目录名称的最后一个元素
我想要的输出:
/usr/local/backup/ure
/usr/local/backup/cheetah
/usr/local/backup/casemgt
/usr/local/backup/royalliver
/usr/local/backup/ure_andras
/usr/local/backup/profserv
/usr/local/backup/frontoffice
/usr/local/backup/ure.orig
/usr/local/backup/projectcommon
/usr/local/backup/playground
/usr/local/backup/casegen
我几乎被困在这一点上。有谁可以帮我离开这里吗? 提前致谢, 戴夫
【问题讨论】:
【参考方案1】:你在正确的轨道上。试试这个:
find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -printf "%f\0" | xargs -0 -I echo svnadmin hotcopy /usr/local/svn/repos/\\ /usr/local/backup/\\
%f
就像basename
和 null 加上 xargs 上的 -0
确保带有空格等的名称成功传递。
只需删除 echo
并进行您可能需要的任何调整,它应该可以解决问题。
【讨论】:
我发现这个解决方案是完美的。谢谢丹尼斯。【参考方案2】:在末尾添加一个剪切命令
find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup \| cut -f1,2,3,9 -d"/"
【讨论】:
【参考方案3】:添加一个sed
过滤器如何去掉中间部分?
sed 's/usr.local.svn.repos.//g'
这样添加
find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup ";" | sed 's/usr.local.svn.repos.//g'
【讨论】:
【参考方案4】:ls -al /usr/local/svn/repos/ |grep '^d' |sed s/^...............................................................//" |xargs -L 1 -I zzyggy echo /usr/local/svn/repos/zzyggy
它有点长,但它可以解决问题。当有很多其他的 shell 命令时,你不必用 find 做所有事情,尽管如果我必须编写这种脚本,我会用 Python 来完成,然后让 shell 进行交互工作。
ls -al
列出命名目录中所有文件的属性
grep '^d'
选择以 d 开头的行,它们是目录
sed
去除实际目录名称左侧的所有字符。您可能需要添加或删除一些点
xargs
获取目录名称列表并一次发出一个。我将 zzyggy 指定为要在执行的命令中替换的名称,但您可以选择自己喜欢的名称。当然,你可以用你的 svnadmin 命令替换 echo。
如果它是在 shell 脚本中,你真的应该这样做
SVNDIRNAME="/usr/local/svn/repos"
ls -al $SVNDIRNAME |grep '^d' |sed s/^...............................................................//" |xargs -L 1 -I zzyggy echo $SVNDIRNAME/zzyggy
但我决定展示错误和正确的方式来解释这一点。我打算用一些 shell 标记来标记它,但我仍然认为 Python 脚本是解决 21 世纪这类问题的更好方法。
【讨论】:
说到“交互式工作”,ls
并不是真正设计来做这种事情的,find
非常适合它。另外,也许您的sed
不理解's/^.\27\//'
? (我没有数你的点,所以这只是一个猜测)。如果您得到像这样解析ls
,至少使用cut
而不是这个可笑的sed
命令。 “我决定展示错误和正确的方式” - 使用变量会有所不同吗?抱歉,您刚刚为自己赢得了 21 世纪的反对票。
就像我说的,如果我真的有这份工作要做,我会写一个 Python 脚本。 Shell 编程在当时还可以,但我们越快克服它就越好。以上是关于如何使用 FIND 递归备份多个颠覆存储库的主要内容,如果未能解决你的问题,请参考以下文章