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

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

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


Обновить

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

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


person Jake McGraw    schedule 12.08.2008    source источник
comment
getdropbox.com (упомянутый Скоттом) обнаружит изменения файлов в каталоге Dropbox и его подкаталогах (пока вы работаете с ними), а затем автоматически отправит изменения на все компьютеры, которые связаны с вашей учетной записью Dropbox.   -  person jfs    schedule 14.11.2008
comment
Вы просматриваете SyncThing (https://syncthing.net/)?   -  person will    schedule 28.04.2020


Ответы (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 (по состоянию на 16 августа 2008 г.).

person dwj    schedule 12.08.2008
comment
На самом деле -a подразумевает -r. См. man rsync. - person Anton Rudeshko; 05.11.2014
comment
Это двунаправленный? - person ThorSummoner; 21.07.2015
comment
@dwj, возможно, вы захотите изменить свой ответ, чтобы использовать SSH, поскольку напрямую rsync иногда может быть закрытым портом (чаще, чем SSH). - person einpoklum; 25.09.2015
comment
Какую синхронизацию это даст? Поддерживать удаленные каталоги в актуальном состоянии с локальными? Наоборот? Или он будет синхронизировать оба направления и сохранять новейшее? - person Chris Smith; 29.10.2015
comment
есть ли ответ на однонаправленный/двунаправленный вопрос? - person rivu; 21.09.2020

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

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

Цитата с гитхаба:

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

person juwens    schedule 07.03.2013
comment
Это лучше, он будет синхронизировать файлы только при обнаружении изменений. - person FaceBro; 19.03.2014
comment
похоже на то, что я искал несколько недель назад!! Пробовал unison, какие-то толстые файлообменники, sshfs: все бесполезно. IMHO rsync не стоит рассматривать для этой задачи (если только мы не хотим тратить время на его настройку вместе с inotify или эквивалентом) ... lsyncd пока выглядит хорошо! - person Shautieh; 16.09.2015
comment
Что произойдет, если изменения произойдут, когда ваш компьютер не подключен к удаленному? Будет ли lsyncd сохранять записи об этих изменениях на потом? - person einpoklum; 25.09.2015

Что вы хотите сделать для удаленного доступа Linux, так это использовать «sshfs» — файловую систему SSH.

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

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

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

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

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

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

Если у вас очень большая структура каталогов и вам нужно уменьшить накладные расходы на опрос, вы можете использовать «найти»:

# 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

person KevinButler    schedule 14.11.2008
comment
Э-э, ссылка на ваш блог не содержит подробностей о том, как обращаться с sshfs как с сетевым подключением. - person ThorSummoner; 21.07.2015
comment
Какое преимущество у sshfs перед синхронизацией напрямую с удаленным хостом в этой ситуации? это кажется ненужными накладными расходами, и по моему опыту sshfs может иногда отключаться. - person nick fox; 23.12.2016

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

person Marie Fischer    schedule 13.08.2008

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

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

  • Убедитесь, что у вас установлен файлообменник
  • Сохраните этот скрипт в /usr/local/bin/livesync или где-нибудь в вашем $PATH и сделайте его исполняемым.
  • Используйте Nautilus для подключения к удаленному хосту (sftp или ftp)
  • Запустите этот скрипт, выполнив livesync SOURCE DEST.
  • Каталог DEST будет находиться в /home/[имя пользователя]/.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
person webasdf    schedule 07.12.2010

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

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

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

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

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

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

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

person icco    schedule 12.08.2008

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

person Pat Notz    schedule 12.08.2008

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

Я протестировал 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-keygen : https://superuser.com/ а/555800/510714

person doom    schedule 22.06.2019

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

person stimms    schedule 13.08.2008

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

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

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

person Daniel Papasian    schedule 16.09.2008

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

person Scott    schedule 22.09.2008

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

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

person k2k2e6    schedule 20.02.2015

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

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

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

person iPatch    schedule 13.01.2012

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

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

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

person Matthew Schinckel    schedule 18.08.2008

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

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

    1.1. Когда вы закончите, проверьте, все ли в порядке… если вы не можете войти без пароля, возможно, вам нужно попробовать монтирование afp. 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.

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

person Eduardo Russo    schedule 21.01.2013

Я использую этот маленький 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

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

person Mike Mitterer    schedule 27.06.2014

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

person deserve    schedule 09.05.2019