Держите удаленный каталог в актуальном состоянии

Мне очень нравится функция « Держать удаленный каталог в актуальном состоянии» в Winscp . К сожалению, я не могу найти ничего более простого в использовании в OS X или Linux. Я знаю, что теоретически то же самое можно сделать с помощью changedfiles или rsync , но я всегда обнаруживал, что учебники для обоих инструментов отсутствуют и / или противоречат друг другу.

Мне просто нужен инструмент, который работает в OSX или Linux и поддерживает синхронизацию удаленного каталога (зеркальное отображение) с локальным каталогом, пока я вношу изменения в локальный каталог.


Обновлять

Просматривая решения, я вижу пару, которые решают общую проблему синхронизации удаленного каталога с локальным каталогом вручную . Я знаю, что могу установить задачу cron для запуска rsync каждую минуту, и это должно быть довольно близко к реальному времени.

Это не то решение, которое я искал, поскольку winscp делает это и многое другое: он обнаруживает изменения файлов в каталоге (пока я над ними работаю), а затем автоматически отправляет изменения на удаленный сервер. Я знаю, что это не лучшее решение (без репозитория кода), но оно позволяет мне очень быстро тестировать код на сервере, пока я его разрабатываю. Кто-нибудь знает, как объединить rsync с любыми другими командами, чтобы получить эту функциональность?

Ответов (17)

Решение

Насколько "в реальном времени" вы хотите синхронизацию? Я бы по-прежнему склонялся к rsync, поскольку вы знаете, что он будет полностью поддерживаться на обеих платформах (в том числе в Windows с cygwin), и вы можете запустить его через задание cron. У меня есть супер-простой файл bash, который я запускаю в своей системе (он не удаляет старые файлы):

#!/bin/sh
rsync -avrz --progress --exclude-from .rsync_exclude_remote . [email protected]_computer:remote_dir    

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

Лучше всего настроить его и попробовать. -n (--dry-run) Вариант является вашим другом!

Имейте в виду, что rsync (по крайней мере, в cygwin) не поддерживает имена файлов в формате Unicode (по состоянию на 16 августа 2008 г.).

Чтобы обнаружить измененные файлы, вы можете попробовать fam (монитор изменения файлов) или inotify. Последний специфичен для Linux, у fam есть порт bsd, который может работать в OS X. У обоих есть инструменты пользовательского пространства, которые можно использовать в скрипте вместе с rsync.

Раньше у меня была такая же настройка под Windows, что и у вас, то есть локальное файловое дерево (с версией) и тестовая среда на удаленном сервере, которую я сохранял в режиме реального времени с помощью WinSCP. Когда я переключился на Mac, мне пришлось немного покопаться, прежде чем я был счастлив, но в конце концов я использовал:

  • SmartSVN в качестве моего подрывного клиента
  • Sublime Text 2 в качестве моего редактора (уже использовал его в Windows)
  • SFTP-плагин для ST2, который обрабатывает загрузку при сохранении (извините, не могу разместить более двух ссылок)

Я действительно могу порекомендовать эту установку, надеюсь, она поможет!

Что ж, у меня была такая же проблема, и я могу использовать их вместе: rsync, SSH Passwordless Login, Watchdog (утилита синхронизации Python) и Terminal Notifier (утилита уведомления OS X, созданная с помощью Ruby. Не требуется, но помогает узнать после завершения синхронизации).

  1. Я создал ключ для входа без пароля, используя этот учебник из вики Dreamhost: http://cl.ly/MIw5

    1.1. Когда вы закончите, проверьте, все ли в порядке ... если вы не можете войти в систему без пароля, возможно, вам нужно попробовать afp mount. Dreamhost (где находится мой сайт) не позволяет монтировать afp, но разрешает вход без пароля. В терминале введите:

    ssh [email protected] Вам необходимо войти в систему без запроса пароля: P

  2. Я установил Terminal Notifier со страницы 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/ [email protected]:site_folder/ terminal-notifier -message "Sync has finished"

    3.1. Не забудьте дать разрешение на выполнение этому сценарию sh. В Терминале введите:

    sudo chmod 777 ~/Scripts/sync.sh 3.2. Запустите сценарий и проверьте, правильно ли отображаются сообщения и что rsync действительно синхронизирует вашу локальную папку с удаленной папкой.

  4. Наконец, я загрузил и установил Watchdog со страницы Github: http://cl.ly/MJfb

    4.1. Во-первых, я установил зависимость libyaml с помощью Brew (есть много подсказок, как установить Brew - например, «aptitude» для OS X). В Терминале введите:

    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.

    Теперь внесите некоторые изменения в файл внутри папки и наблюдайте за волшебством!

lsyncd кажется идеальным решением. он сочетает в себе inotify (встроенную функцию ядра, которая отслеживает изменения файлов в деревьях каталогов) и rsync (кроссплатформенный инструмент для синхронизации файлов).

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

Цитата из github:

Lsyncd наблюдает за интерфейсом монитора событий дерева каталогов (inotify или fsevents). Он агрегирует и объединяет события в течение нескольких секунд, а затем запускает один (или несколько) процессов для синхронизации изменений. По умолчанию это rsync. Таким образом, Lsyncd представляет собой легкое решение с «живым» зеркалом, которое сравнительно легко установить, не требуя новых файловых систем или блочных устройств, и не снижает производительность локальной файловой системы.

Я использую этот маленький Ruby-Script:

#!/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

Адаптируйте его под свои нужды!

Пользователь watcher.py и rsync для автоматизации этого. Прочтите следующие пошаговые инструкции здесь:

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

Если вы разрабатываете Python на удаленном сервере, Pycharm может быть для вас хорошим выбором. Вы можете синхронизировать ваши удаленные файлы с вашими локальными файлами, используя функцию удаленной разработки pycharm. Ссылка на руководство: https://www.jetbrains.com/help/pycharm/creating-a-remote-server-configuration.html

Отличный вопрос, ответ на который я искал часами!

Я тестировал lsyncd, и проблема в том, что задержка по умолчанию слишком велика, и ни одна из примеров командной строки не дает такой -delay возможности.

Другая проблема в том, что по умолчанию rsync каждый раз запрашивает пароль !

Решение с lsyncd :

lsyncd --nodaemon -rsyncssh local_dir [email protected]_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 [email protected]_host:remote_dir
done

Для этого второго решения вам нужно будет установить inotify-tools пакет

Чтобы подавить необходимость вводить пароль при каждом изменении, просто используйте ssh-keygen : https://superuser.com/a/555800/510714

Эти rsync решения очень хороши, особенно если вы только толкая меняющий путь. Еще один отличный инструмент unison - он пытается синхронизировать изменения в обоих направлениях. Узнайте больше на домашней странице Unison .

Вы всегда можете использовать контроль версий, например SVN, поэтому все, что вам нужно сделать, это заставить сервер запускать svn для папки каждую ночь. Это вызывает проблемы с безопасностью, если вы делитесь своими файлами публично, но это работает.

Если вы используете Linux, научитесь использовать rsync. На самом деле это не так сложно, поскольку вы можете проверить каждую команду с помощью -n. Просмотрите страницу руководства, основной формат, который вам понадобится, это

rsync [ОПЦИЯ ...] SRC ... [ПОЛЬЗОВАТЕЛЬ @] HOST: DEST

команда, которую я запускаю со школьного сервера на домашнюю резервную машину, такова

rsync -avi --delete ~ я @ homeserv: ~ / Школа / >> BackupLog.txt

Это берет все файлы в моем домашнем каталоге (~) и использует режим архива rsync (-a), подробный (-v), перечисляет все сделанные изменения (-i), удаляя при этом любые файлы, которые больше не существуют (--delete) и помещает в папку / home / me / School / на моем удаленном сервере. Вся информация, которую он распечатывает (что было скопировано, что было удалено и т. Д.), Также добавляется в файл BackupLog.txt.

Я знаю, что это бурный тур по rsync, но надеюсь, что это поможет.

Похоже, вы решаете не ту проблему. Если вы пытаетесь редактировать файлы на удаленном компьютере, вы можете попробовать использовать что-то вроде плагина ftp для jedit. http://plugins.jedit.org/plugins/?FTP Это гарантирует, что у вас есть только одна версия файла, поэтому она никогда не будет рассинхронизирована.

Вы также можете использовать Fetch в качестве клиента SFTP, а затем редактировать файлы прямо на сервере из него. Есть также параметры SSHFS (монтировать папку ssh как том). Это соответствует тому, что сказано в стиммах - вы уверены, что хотите, чтобы все было синхронизировано, или просто хотите редактировать файлы на сервере?

В OS X есть собственная система уведомлений о файлах - это то, на чем основан Spotlight. Я не слышал о какой-либо программе, которая использует это для синхронизации, но это, безусловно, возможно.

Я лично использую RCS для такого рода вещей: - хотя он имеет ручной аспект, маловероятно, что я захочу подтолкнуть что-то даже на тестовый сервер с моей машины разработчика без предварительного тестирования. А если я работаю на сервере разработки, то использую один из вариантов, приведенных выше.

Основываясь на предложении icco о SVN, я бы на самом деле предположил, что если вы используете Subversion или аналогичный для управления версиями (а если нет, вам, вероятно, следует начать), вы можете поддерживать производственную среду в актуальном состоянии, поместив команду чтобы обновить репозиторий в ловушке после фиксации.

Есть много переменных в том, как вы хотели бы это сделать, но то, что я видел, работает, это то, что разрабатываемый или действующий сайт является рабочей копией, а затем после фиксации используется ключ ssh с принудительной командой для войдите на удаленный сайт и вызовите svn на рабочей копии. В качестве альтернативы в хуке post-commit вы можете запустить экспорт svn на удаленном компьютере или локальный (в репозиторий svn) экспорт svn, а затем rsync на удаленный компьютер.

Я бы беспокоился о вещах, которые обнаруживают изменения и подталкивают их, и я даже беспокоился бы о вещах, которые выполняются каждую минуту, просто из-за условий гонки. Откуда вы знаете, что он не будет передавать файл в тот же момент, в который он записывается? Наткнитесь на это один или два раза, и вы потеряете все преимущество экономии времени, которое у вас было из-за постоянной синхронизации или чего-то подобного.

Будет ли DropBox ( http://www.getdropbox.com/ ) делать то, что вы хотите?

Для удаленного доступа Linux вы хотите использовать sshfs - файловую систему SSH.

# sshfs [email protected]:path/to/directory local_dir

Тогда относитесь к нему как к сетевому монтированию, а это ...

Немного подробнее, например, как его настроить, чтобы вы могли делать это как обычный пользователь, в моем блоге.

Если вам нужно асинхронное поведение winSCP, вы захотите использовать rsync в сочетании с чем-то, что выполняет его периодически. Приведенное выше решение cron работает, но может оказаться излишним для варианта использования winscp.

Следующая команда будет выполнять rsync каждые 5 секунд, чтобы отправить контент на удаленный хост. Вы можете настроить время сна по мере необходимости, чтобы снизить нагрузку на сервер.

# while true; do rsync -avrz localdir [email protected]: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 [email protected]:path; else echo -ne .; fi; sleep 5; done

И я сказал, что cron может быть излишним? Но, по крайней мере, это все просто делается из командной строки и может быть остановлено с помощью ctrl-C.

kb

У меня такая же проблема. Мне очень понравилась команда winscp «обновлять удаленный каталог». Однако в моем стремлении избавиться от Windows я потерял winscp. Я написал сценарий, который использует fileschanged и rsync, чтобы делать что-то подобное, намного ближе к реальному времени.

Как использовать:

  • Убедитесь, что у вас установлены измененные файлы
  • Сохраните этот скрипт в / usr / local / bin / liveync или где-нибудь доступном в вашем $ PATH и сделайте его исполняемым
  • Используйте Nautilus для подключения к удаленному хосту (sftp или ftp)
  • Запустите этот сценарий, выполнив lifeync SOURCE DEST
  • Каталог DEST будет в /home/[usernamepting/.gvfs/[путь к ftp scp или какому-то другому]

Пара минусов:

  • Он медленнее, чем winscp (я предполагаю, потому что он проходит через Nautilus и также должен обнаруживать изменения через rsync)
  • Вам необходимо вручную создать целевой каталог, если он еще не существует. Поэтому, если вы добавляете каталог, он не будет обнаруживать и создавать каталог на стороне DEST.
  • Наверное, больше того, чего я еще не заметил
  • Также не пытайтесь синхронизировать каталог SRC с именем «rsyncThis». Наверное, это будет нехорошо :)

#!/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