使远程目录保持最新

时间:2008-08-12 21:56:10

标签: linux macos ssh sftp

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

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


更新

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

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

17 个答案:

答案 0 :(得分:40)

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

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

引自github:

  

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

答案 1 :(得分:17)

您希望同步“实时”如何?我仍然倾向于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日)。

答案 2 :(得分:8)

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

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

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

更详细一点,比如如何设置,以便您可以在my blog

上以普通用户的身份进行设置

如果你想要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的

答案 3 :(得分:4)

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

答案 4 :(得分:3)

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

使用方法:

  • 确保已安装fileschanged
  • 将此脚本保存在/ usr / local / bin / livesync或$ PATH中可到达的位置并使其可执行
  • 使用Nautilus连接到远程主机(sftp或ftp)
  • 通过执行lifeync SOURCE DEST
  • 运行此脚本
  • DEST目录将在/home/[username]/.gvfs/[path到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

答案 5 :(得分:2)

您可以随时使用版本控制,例如SVN,因此您所要做的就是让服务器每晚在文件夹上运行svn。如果您公开共享文件,这会遇到安全问题,但它可以正常运行。

如果您使用的是Linux,请学会使用rsync。这真的不是那么困难,因为你可以用-n测试每个命令。浏览man page,您需要的基本格式是

  

rsync [OPTION ...] SRC ... [USER @] HOST:DEST

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

  

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

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

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

答案 6 :(得分:2)

rsync解决方案非常好,特别是如果您只是单向推送更改。另一个很棒的工具是unison - 它试图同步两个方向的变化。阅读更多the Unison homepage

答案 7 :(得分:1)

好问题,我已经搜索了好几个小时了!

我已经测试过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

答案 8 :(得分:1)

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

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

答案 9 :(得分:1)

我曾经在Windows下拥有与您相同的设置,即本地文件树(版本化)和远程服务器上的测试环境,我使用WinSCP实时镜像。当我切换到Mac时,在我开心之前我不得不做一些挖掘,但最后还是使用了:

  • SmartSVN作为我的subversion客户端
  • Sublime Text 2作为我的编辑(已经在Windows上使用过)
  • SFTP-plugin到ST2处理保存上传(抱歉,不能发布超过2个链接)

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

答案 10 :(得分:1)

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

答案 11 :(得分:1)

建立icco对SVN的建议,我实际上建议如果你使用subversion或类似的源代码控制(如果你不是,你应该开始),你可以保持生产环境的最新状态将命令放入post-commit hook中。

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

我会担心发现变化并推动它们的事情,我甚至会担心因为竞争条件而每分钟都会发生的事情。你怎么知道它不会在写入文件的同一时刻传输文件?偶然发现一两次,你将失去所有节省时间的优势,不断地使用它们或类似的。

答案 12 :(得分:1)

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

答案 13 :(得分:0)

好吧,我遇到了同样的问题,可以一起使用:rsync,SSH无密码登录,Watchdog(Python同步实用程序)和终端通知程序(使用Ruby制作的OS X通知实用程序。不需要,但是有助于了解同步完成的时间。)

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

    1.1。当你完成后,测试一切是否正常......如果你不能无密码登录,也许你必须尝试afp mount。 Dreamhost(我的网站所在地)不允许afp mount,但允许无密码登录。在终端中,键入:

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

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

    2.1。我使用了Gem installer命令。在终端中,键入:

    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的“aptitude”)。在终端中,键入:

    brew install libyaml

    4.2。然后,我使用了“easy_install命令”。转到Watchdog文件夹,然后输入终端:

    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.

    现在,对文件夹内的文件进行了一些更改,并观看魔术!

答案 14 :(得分:0)

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

答案 15 :(得分:0)

您还可以使用Fetch作为SFTP客户端,然后直接在服务器上编辑文件。还有SSHFS(将ssh文件夹作为卷安装)选项。这与刺激所说的一致 - 你确定要保持同步的东西,或者只想编辑服务器上的文件吗?

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

我个人使用RCS来做这类事情: - 虽然它有一个手动方面,但我不太可能想要从我的开发机器上推送一些东西,而不先测试它。如果我正在开发服务器,那么我使用上面给出的一个选项。

答案 16 :(得分: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

根据您的需求进行调整!