我需要在 FTP 服务器上编辑 PHP 文件,由于我的本地编辑器在保存到 GVFS 挂载时不可靠,所以我让其rsync
进行同步:
#!/bin/bash
webroot=/run/user/1002/gvfs/ftp\:host\=ftp.server.com/
while true
do
inotifywait -r -e create -e modify -e close_write -e moved_to ./ | \
mawk '{ print $1 }' | \
while read f
do
# currently, $f is always a directory (not just the changed file)
echo "rsync $f..."
mkdir -p $webroot"$f"
rsync --exclude "*/" -rlpgoD "$f" $webroot"$f"
done
done
该脚本同步已更改文件的目录,但速度非常慢。这就是我寻求改进的原因。
你会如何编写这样的脚本?理想情况下,它不会同步整个目录,而只会同步更改的文件。
答案1
如果有空间,您可以保留远程层次结构的本地副本。当您的 inotify 由于真实层次结构的更改而触发时,您可以rsync -a -i
在真实副本和本地副本之间使用来更新它并生成实际更改的列表。仅应用此列表来从本地副本 rsync 更新远程。
为了帮助解决这种情况,请参阅 rsync 手册页批处理模式部分。而不是-i
您rsync -a --write-batch=foo
在真实副本和本地副本之间执行的操作,然后rsync -a --read-batch=foo
在远程执行以应用完全相同的更改。 (foo 文件是一个二进制文件,包含所有更改的副本)。
下面是 /tmp 中使用目录 a、b 和 c 的示例,其中 a 是编辑文件的真实目录,b 是远程的本地缓存副本,c 是远程目录。我们首先创建 a 并将其复制到 b 和 c。我已将 c 放入变量中,以便稍后可以更改。
cd /tmp || exit
echo do: rm -fr a b c foo foo.sh
c=c
mkdir a
echo hi >a/f1
echo hi >a/f2
rsync -av a/ b
rsync -av a/ "$c"
我们有 3 个相同的目录。我们编辑目录a。
echo bye >>a/f1
echo bye >>a/f3
rm -f a/f2
我们将 a 同步到 b,创建一个批处理文件 foo:
rsync -av --delete --write-batch=/tmp/foo a/ b
我们现在可以在 c 上重新运行 foo 中保存的更改:
rsync -av --delete --read-batch=/tmp/foo "$c"
现在又出现了 3 个相同的目录。优点是 rsync 只会执行它记录在 foo 文件中的更新。我尝试使用本地 ftp gvfs mount for c 进行此操作,但它不起作用 ( c="$XDG_RUNTIME_DIR/gvfs/ftp:host=localhost,user=ftp/test/"
)。 gvfsd-fuse 挂载似乎非常有问题,并且有时假设远程文件应该是一个目录,因此 rsync 从未使用过它。