44

我非常喜欢Winscp中的Keep Remote Directory Up-to-date功能。不幸的是,我找不到在 OS X 或 Linux 中使用这么简单的东西。我知道理论上可以使用changedfilesrsync完成同样的事情,但我一直发现这两种工具的教程都缺乏和/或矛盾。

我基本上只需要一个在 OSX 或 Linux 中工作的工具,并在我对本地目录进行更改时保持远程目录与本地目录同步(镜像)。


更新

通过解决方案,我看到了一些解决了手动保持远程目录与本地目录同步的一般问题的方法。我知道我可以设置一个 cron 任务来每分钟运行一次 rsync,这应该非常接近实时。

这不是我正在寻找的确切解决方案,因为 winscp 会这样做以及更多:它检测目录中的文件更改(当我处理它们时),然后自动将更改推送到远程服务器。我知道这不是最好的解决方案(没有代码存储库),但它允许我在开发时非常快速地在服务器上测试代码。有谁知道如何将 rsync 与任何其他命令结合使用来获得此功能?

4

17 回答 17

42

lsyncd似乎是完美的解决方案。它结合了inotify(用于监视目录树中文件更改的内核内置函数)和rsync(跨平台文件同步工具)。

lsyncd -rsyncssh /home remotehost.org backup-home/

引用自 github:

Lsyncd 监视本地目录树事件监视器接口(inotify 或 fsevents)。它在几秒钟内聚合和组合事件,然后生成一个(或多个)进程以同步更改。默认情况下这是 rsync。因此,Lsyncd 是一种轻量级的实时镜像解决方案,它相对容易安装,不需要新的文件系统或块设备,也不会影响本地文件系统的性能。

于 2013-03-07T22:30:07.977 回答
19

您希望同步有多“实时”?我仍然倾向于 rsync,因为您知道它将在两个平台(Windows 也一样,带有 cygwin)上得到完全支持,并且您可以通过 cron 作业运行它。我有一个在我的系统上运行的超级简单的 bash 文件(这不会删除旧文件):

#!/bin/sh
rsync -avrz --progress --exclude-from .rsync_exclude_remote . remote_login@remote_computer:remote_dir    

# options
#   -a  archive
#   -v  verbose
#   -r  recursive
#   -z  compress 

您最好的选择是设置并尝试一下。选择是你的-n (--dry-run)朋友!

请记住,rsync(至少在 cygwin 中)不支持 unicode 文件名(截至 2008 年 8 月 16 日)。

于 2008-08-12T22:14:46.830 回答
9

您想要为 linux 远程访问做的是使用 'sshfs' - SSH 文件系统。

# sshfs username@host:path/to/directory local_dir

然后将其视为网络挂载,它是...

更多细节,例如如何设置它,以便您可以作为普通用户执行此操作,在我的博客上

如果您想要 winSCP 的异步行为,您需要将 rsync 与定期执行它的东西结合使用。上面的 cron 解决方案有效,但对于 winscp 用例来说可能有点过分了。

以下命令将每 5 秒执行一次 rsync 以将内容推送到远程主机。您可以根据需要调整休眠时间以减少服务器负载。

# while true; do rsync -avrz localdir user@host:path; sleep 5; done

如果你有一个非常大的目录结构并且需要减少轮询的开销,你可以使用'find':

# touch -d 01/01/1970 last; while true; do if [ "`find localdir -newer last -print -quit`" ]; then touch last; rsync -avrz localdir user@host:path; else echo -ne .; fi; sleep 5; done

我说 cron 可能是矫枉过正?但至少这一切都是从命令行完成的,并且可以通过 ctrl-C 停止。

KB

于 2008-11-14T05:19:26.870 回答
4

要检测更改的文件,您可以尝试 fam(文件更改监视器)或 inotify。后者是特定于 linux 的,fam 有一个 bsd 端口,可以在 OS X 上运行。两者都有用户空间工具,可以与 rsync 一起在脚本中使用。

于 2008-08-13T00:24:41.293 回答
3

我有同样的问题。我喜欢winscp“保持远程目录最新”命令。然而,在我摆脱 Windows 的过程中,我失去了 winscp。我确实编写了一个脚本,它使用 fileschanged 和 rsync 来执行更接近实时的类似操作。

如何使用:

  • 确保已安装 fileschanged
  • 将此脚本保存在 /usr/local/bin/livesync 或 $PATH 中可访问的某个位置并使其可执行
  • 使用 Nautilus 连接到远程主机(sftp 或 ftp)
  • 通过 livesync SOURCE DEST运行此脚本
  • DEST 目录将位于 /home/[username]/.gvfs/[ftp scp 的路径或其他]

几个缺点:

  • 它比 winscp 慢(我的猜测是因为它通过 Nautilus 并且还必须通过 rsync 检测更改)
  • 如果目标目录尚不存在,则必须手动创建它。因此,如果您要添加目录,它不会在 DEST 端检测和创建目录。
  • 可能更多我还没有注意到
  • 此外,不要尝试同步名为“rsyncThis”的 SRC 目录。那可能不太好:)

#!/bin/sh

upload_files()
{
    if [ "$HOMEDIR" = "." ]
    then
        HOMEDIR=`pwd`
    fi

    while read  input
    do
        SYNCFILE=${input#$HOMEDIR}
        echo -n "Sync File: $SYNCFILE..."
        rsync -Cvz --temp-dir="$REMOTEDIR" "$HOMEDIR/$SYNCFILE" "$REMOTEDIR/$SYNCFILE" > /dev/null
        echo "Done."
    done
}


help()
{
    echo "Live rsync copy from one directory to another.  This will overwrite the existing files on DEST."
    echo "Usage: $0 SOURCE DEST"    
}


case "$1" in
  rsyncThis)
    HOMEDIR=$2
    REMOTEDIR=$3
    echo "HOMEDIR=$HOMEDIR"
    echo "REMOTEDIR=$REMOTEDIR"
    upload_files
    ;;

  help)
    help
    ;;

  *)
    if [ -n "$1" ] && [ -n "$2" ]
    then
        fileschanged -r "$1" | "$0" rsyncThis "$1" "$2"
    else
        help
    fi
    ;;
esac
于 2010-12-07T16:20:21.923 回答
2

你总是可以使用版本控制,比如 SVN,所以你所要做的就是让服务器每晚在一个文件夹上运行 svn up。如果您公开共享文件,这会遇到安全问题,但它确实有效。

如果您使用的是 Linux,请学习使用 rsync。这真的没那么难,因为您可以使用 -n 测试每个命令。浏览手册页,您需要的基本格式是

rsync [选项...] SRC... [USER@]HOST:DEST

我从学校服务器运行到家庭备份机的命令是这样的

rsync -avi --delete ~ me@homeserv:~/School/ >> BackupLog.txt

这将获取我的主目录 (~) 中的所有文件,并使用 rsync 的存档模式 (-a)、详细 (-v)、列出所做的所有更改 (-i),同时删除任何不再存在的文件(--delete) 并将其放在我的远程服务器上的文件夹 /home/me/School/ 中。它打印出的所有信息(复制的内容、删除的内容等)也附加到文件 BackupLog.txt

我知道这是 rsync 的旋风之旅,但我希望它有所帮助。

于 2008-08-12T22:17:34.297 回答
2

rsync解决方案非常好,特别是如果您只是以一种方式推动更改。另一个很棒的工具是unison——它试图同步两个方向的变化。在Unison 主页上阅读更多内容。

于 2008-08-12T23:01:14.880 回答
2

好问题我已经搜索了几个小时的答案!

我已经测试了 lsyncd,问题是默认延迟太长了,并且没有示例命令行提供该-delay选项。

另一个问题是,默认情况下 rsync每次都询问密码!

使用lsyncd的解决方案:

lsyncd --nodaemon -rsyncssh local_dir remote_user@remote_host remote_dir -delay .2

另一种方法是在脚本中使用inotify-wait :

while inotifywait -r -e modify,create,delete local_dir ; do
    # if you need you can add wait here
    rsync -avz local_dir remote_user@remote_host:remote_dir
done

对于第二个解决方案,您必须安装inotify-tools

禁止在每次更改时输入密码,只需使用ssh-keygenhttps ://superuser.com/a/555800/510714

于 2019-06-22T17:57:37.143 回答
1

似乎您正在解决错误的问题。如果您尝试在远程计算机上编辑文件,那么您可以尝试使用 jedit 的 ftp 插件之类的东西。 http://plugins.jedit.org/plugins/?FTP 这确保您只有一个文件版本,因此它永远不会不同步。

于 2008-08-13T00:32:05.897 回答
1

基于 icco 对 SVN 的建议,我实际上建议,如果您使用 subversion 或类似工具进行源代码控制(如果不是,您可能应该开始),您可以通过输入命令使生产环境保持最新将存储库更新到提交后挂钩。

您希望如何做到这一点有很多变数,但我所看到的工作是让开发或实时站点成为工作副本,然后让提交后使用带有强制命令的 ssh 密钥登录远程站点并在工作副本上触发 svn up。或者,在 post-commit 钩子中,您可以触发远程机器上的 svn 导出,或本地(到 svn 存储库)svn 导出,然后 rsync 到远程机器。

我会担心检测到变化并推动它们的事情,我什至会担心每分钟运行的事情,只是因为竞争条件。你怎么知道它不会在文件被写入的同一时刻传输文件?偶然发现一次或两次,您将失去通过不断进行 rsync 或类似操作而获得的所有节省时间的优势。

于 2008-09-16T15:13:37.330 回答
1

DropBox ( http://www.getdropbox.com/ ) 会做你想做的事吗?

于 2008-09-22T02:23:01.850 回答
1

我以前在 Windows 下的设置与您相同,即本地文件树(版本化)和远程服务器上的测试环境,我使用 WinSCP 实时镜像。当我切换到 Mac 时,我不得不做一些挖掘工作才能感到高兴,但最终还是使用了:

  • SmartSVN作为我的颠覆客户端
  • Sublime Text 2作为我的编辑器(已经在 Windows 上使用过)
  • ST2 的 SFTP 插件,用于处理保存时的上传(抱歉,不能发布超过 2 个链接)

我真的可以推荐这个设置,希望它有帮助!

于 2012-01-13T17:20:32.110 回答
1

用户 watcher.py 和 rsync 可以自动执行此操作。在此处阅读以下分步说明:

http://kushellig.de/linux-file-auto-sync-directories/

于 2015-02-20T18:39:19.347 回答
0

您还可以将 Fetch 用作 SFTP 客户端,然后在其中直接在服务器上编辑文件。还有 SSHFS(将 ssh 文件夹挂载为卷)选项。这与 stimms 所说的一致 - 您确定要保持同步,还是只想编辑服务器上的文件?

OS X 有它自己的文件通知系统——这就是 Spotlight 的基础。我还没有听说过任何使用它来保持同步的程序,但这当然是可以想象的。

我个人将 RCS 用于此类事情:- 虽然它具有手动方面,但我不太可能在不先测试的情况下从我的开发机器将某些东西推送到测试服务器。如果我在开发服务器上工作,那么我会使用上面给出的选项之一。

于 2008-08-18T14:41:18.473 回答
0

好吧,我遇到了同样的问题,可以一起使用:rsync、SSH Passwordless Login、Watchdog(一个 Python 同步实用程序)和 Terminal Notifier(一个用 Ruby 制作的 OS X 通知实用程序。不需要,但有助于了解同步完成时)。

  1. 我使用 Dreamhost wiki 中的本教程创建了无密码登录的密钥:http: //cl.ly/MIw5

    1.1。完成后,测试一切是否正常……如果您无法无密码登录,也许您必须尝试 afp mount。Dreamhost(我的站点所在的位置)不允许挂载 afp,但允许无密码登录。在终端中,键入:

    ssh username@host.com 您应该在不询问密码的情况下登录:P

  2. 我从 Github 页面安装了终端通知程序:http: //cl.ly/MJ5x

    2.1。我使用了 Gem 安装程序命令。在终端中,键入:

    gem install terminal-notifier

    2.3. 测试通知是否有效。在终端中,键入:

    terminal-notifier -message "Starting sync"

  3. 创建一个 sh 脚本来测试 rsync + 通知。以您喜欢的名称将其保存在您喜欢的任何位置。在此示例中,我将其命名为~/Scripts/sync.sh我使用了“.sh 扩展名,但我不知道是否需要它。

    #!/bin/bash terminal-notifier -message "Starting sync" rsync -azP ~/Sites/folder/ user@host.com:site_folder/ terminal-notifier -message "Sync has finished"

    3.1。记得给这个 sh 脚本执行权限。在终端中,键入:

    sudo chmod 777 ~/Scripts/sync.sh 3.2. 运行脚本并验证消息是否正确显示以及 rsync 是否实际将您的本地文件夹与远程文件夹同步。

  4. 最后,我从 Github 页面下载并安装了 Watchdog:http: //cl.ly/MJfb

    4.1。首先,我使用 Brew 安装了 libyaml 依赖项(有很多关于如何安装 Brew 的帮助 - 就像 OS X 的“能力”)。在终端中,键入:

    brew install libyaml

    4.2. 然后,我使用了“easy_install 命令”。进入看门狗文件夹,输入终端:

    easy_install watchdog

  5. 现在,一切都安装好了!转到您要同步的文件夹将此代码更改为您的需要,然后输入终端:

      watchmedo shell-command
          --patterns="*.php;*.txt;*.js;*.css" \
          --recursive \
          --command='~/Scripts/Sync.sh' \
          .
    

    它必须完全这样,带有斜杠和换行符,所以你必须将这些行复制到文本编辑器,更改脚本,粘贴到终端并按回车键。

    我试过没有换行符,它不起作用!

    在我的 Mac 中,我总是收到一个错误,但它似乎没有影响任何事情:

    /Library/Python/2.7/site-packages/argh-0.22.0-py2.7.egg/argh/completion.py:84: UserWarning: Bash completion not available. Install argcomplete.

    现在,对文件夹内的一个文件进行一些更改,看看魔术吧!

于 2013-01-21T09:25:35.473 回答
0

我正在使用这个小 Ruby 脚本:

#!/usr/bin/env ruby
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Rsyncs 2Folders
#
# watchAndSync by Mike Mitterer, 2014 <http://www.MikeMitterer.at>
# with credit to Brett Terpstra <http://brettterpstra.com>
# and Carlo Zottmann <https://github.com/carlo/haml-sass-file-watcher>
# Found link on: http://brettterpstra.com/2011/03/07/watch-for-file-changes-and-refresh-your-browser-automatically/
#

trap("SIGINT") { exit }

if ARGV.length < 2
  puts "Usage: #{$0} watch_folder sync_folder"
  puts "Example: #{$0} web keepInSync"
  exit
end

dev_extension = 'dev'
filetypes = ['css','html','htm','less','js', 'dart']

watch_folder = ARGV[0]
sync_folder = ARGV[1]

puts "Watching #{watch_folder} and subfolders for changes in project files..."
puts "Syncing with #{sync_folder}..."

while true do
  files = []
  filetypes.each {|type|
    files += Dir.glob( File.join( watch_folder, "**", "*.#{type}" ) )
  }
  new_hash = files.collect {|f| [ f, File.stat(f).mtime.to_i ] }
  hash ||= new_hash
  diff_hash = new_hash - hash

  unless diff_hash.empty?
    hash = new_hash

    diff_hash.each do |df|
      puts "Detected change in #{df[0]}, syncing..."
      system("rsync -avzh #{watch_folder} #{sync_folder}")
    end
  end

  sleep 1
end

根据您的需要进行调整!

于 2014-06-27T15:36:31.813 回答
0

如果你在远程服务器上开发 python,Pycharm 可能是你的一个不错的选择。您可以使用 pycharm 远程开发功能将远程文件与本地文件同步。指南链接为: https ://www.jetbrains.com/help/pycharm/creating-a-remote-server-configuration.html

于 2019-05-09T02:52:21.810 回答