要使 rsync cronjob 正常工作,我需要先在远程服务器上创建目录树,然后再运行 rsync。本地目录应镜像(无内容)到远程服务器。我正在努力做到这一点。
我需要的是这样的 stg:
find /home/local_directories/onedir/* -type d -exec sh -c "ls -dlts {}" \; |
cut -d" " -f10 | uniq | ssh user@server mkdir -p /tmp/{xargs}
难点在于如何让最后一根管道运行起来?
编辑:rsync 命令如下(也尝试使用 -R):
/usr/bin/rsync -e ssh -arz --stats --force /home/local_directories/onedir/ user@server:port:/exitsing/path/to/remote/dir/
源树是 svn hotcopy (/conf、/db、/hooks、/dav、...)
谢谢
答案1
目前尚不清楚为什么需要使用 创建所有这些目录mkdir
。
您唯一需要创建的目录是目标目录本身,并且只有在它不存在的情况下才需要创建。 如果您使用或选项rsync
,将创建所有子目录。-a
-v
像这样的事情就足够了:
destdir="/home/local_directories/onedir.bak" # or wherever it should go
ssh user@server "mkdir \"$destdir\""
rsync -a /home/local_directories/onedir/ user@server:"$destdir"
或者更正确地说(如果目录不存在则仅创建目录):
destdir="/home/local_directories/onedir.bak"
ssh user@server 'destdir="'"$destdir"'"; test -d "$destdir" || mkdir -p "$destdir"'
rsync -a /home/local_directories/onedir/ user@server:"$destdir"
但如果你真的必须这样做,出于某种原因ls -ltds
真的是必需的,那么你必须修复你的{xargs}
位才能使其运行。
我能想到的完成最后一点最正确、最有效的方法是:
find ... |
ssh user@server 'while IFS=$'"\n"' read -r dir; do test -d "$dir" || mkdir -p "$dir"; done'
其背后的想法是,我们只启动find
和ssh
一次。我们在管道中同时启动find
和,并通过将其输出发送到远程服务器。ssh
find
ssh
find
每个文件产生一行输出,然后while read
另一端的循环一次读取一行,并对其执行某些操作(在本例中是创建目录)。
如果您使用xargs
,它将会运行ssh
多次,这会使速度变慢。
更好,但有点复杂,是:
find ... -print0 |
ssh user@server 'while read -r -d "$(printf "\000")" -r dir; do test -d "$dir" || mkdir -p "$dir"; done'
这样更好,因为它可以处理文件中的奇怪字符,包括换行符,这些字符非常罕见,而且是个坏主意,但最好还是处理它们以防万一。
据我所知,你应该做类似的事情:
find /home/local_directories/onedir/ -type d -print0 |
ssh user@server 'while read -r -d "$(printf "\000")" -r dir; do test -d "$dir" || mkdir -p "$dir"; done'
答案2
我不太明白你在这里想要实现什么。我一直使用 rsync,从未在服务器上预先创建任何目录。
rsync -avP /home/local_directories/onedir/ user@server:/where/to/sync/to/
应该只将 onedir 下的整个树从本地镜像到远程。