如何使用 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 递归备份多个颠覆存储库的主要内容,如果未能解决你的问题,请参考以下文章

如何显示来自颠覆服务器的存储库列表

如何监视远程只读颠覆存储库的提交更改?

OracleRMAN物理备份技术之管理维护

使用 Rsync 备份多个 Git 存储库时使用删除标志?

xcode 颠覆设置以连接到基于网络的存储库

可以与 Eclipse 颠覆插件一起使用的最好的、免费的颠覆控制存储库是啥? [关闭]