Перенос файлов между серверами напрямую по SSH через SCP

Опубликовано в Веб-разработка

Как организовать перенос файлов между серверами, когда объемы данных очень велики и нет возможности архивации и промежуточного сохранения?

На работе появилась такая задача: миграция на другой сервер. Мы меняли хостинг-провайдера, т.к. заканчивалось свободное дисковое пространство аккаутов, да и условия сотрудничества уже разонравились.

На момент миграции у нас было 2 аккаунта, каждый по 20Гб дискового пространства, в итоге мы должны были все перенести на 1 аккаунт с объемом дискового пространства равным 60Гб.

По-старинке это выглядело бы примитивно и примерно так: заархивировать небольшой объем информации в ZIP-архив, сохранить с сервера на локальный компьютер, затем с локального компьютера перенести на удаленный сервер по FTP или SFTP. Но не в этот раз... Ведь у нас было достаточно большое количество интернет-проектов, перенос которых изначально становился кропотливым делом, а беря в расчет, что свободного места на каждом из аккаунтов оставалось чуть менее 2Гб, вариант архивации на сервере был невозможен.

Поэтому, недолго думая, я полез в гугл с запросом "ssh copy files from one server to another directly". В итоге решение оказалось довольно простым, единственное условие - наличие SHH на серверах, между которыми будет осуществляться обмен данными.

Итак, для этого понадобится команда 

scp -r /path/to/local/file remote_user@remote_host:/path/to/remote/file

Что она означает:

  • scp - мы сообщаем серверу название утилиты, через которую будут обрабатываться эти команды;
  • -r - параметр, говорящий о том, что копируемая папка (если это папка) должна копироваться рекурсивно, т.е. со всеми вложенными подпапками. Если копируется не папка, можно удалить этот параметр из команды;
  • /path/to/local/file - путь к локальному файлу, в мое случае к файлу сервера, с которого будет осуществлен перенос данных;
  • remote_user@remote_host - данные для подключения к удаленному серверу, которые имеют вид [имя_пользователя]@[адрес_сервера];
  • /path/to/remote/file - путь к конечной папке сервера, куда будут загружены файлы.

Предостерегая вас от двойной работы и вопросов:

  1. пути к копируемым папкам/файлам нужно вводить абсолютные. Это значит, если, допустим, у вас есть аккаунт у хостинг-провайдера и называется он vaspupkin1, вероятней всего, что он находится в папке наряду с остальными аккаунтами пользователей и может иметь полный путь от корня сервера такой: /home/w/vaspupkin1, в то время как файлы сайта могут лежать в папке /home/w/vaspupkin1/public_html . Поэтому, чтобы скопировать папку с сайтом на другой сервер, мы должны в первой части команды scp после параметра -r ввести следующее: /home/w/vaspupkin1/public_html, в то время, когда вы, подключаясь к своему аккаунту по FTP, сразу попадаете в папку /vaspupkin1, что является относительным, а не абсолютным путем.
  2. при копировании папки описанным выше образом на удаленном сервере создается эта же папка. Т.е. когда вы, копируя папку /home/w/vaspupkin1/public_html, вводите конечный адрес типа /var/i/vaspupkin1/http_docs, подразумевая, что структура папки public_html будет скопирована в папку http_docs, то ничего подобного не произойдет, в итоге у вас получится это - /var/i/vaspupkin1/http_docs/public_html, имейте это ввиду.

Если файлы нужно скопировать с удаленного сервера на локальный, тогда исползуем эту же команду, поменяв местами конечный и начальны пути копирования: scp -r remote_user@remote_host:/path/to/remote/file /path/to/local/file. Если копируется не папка, можно удалить параметр -r из команды.

Обновление от 26.06.2019

Одним из способов передать в SCP пароль является использование утилиты sshpass. В зависимости от направления копирования используйте команды, описанные в этой статье ранее. Ниже, в качестве примера, приведена команда для копирования информации с локального сервера (к которому сейчас подключен пользователь) на удаленный сервер, где для удаленного сервера необходимо ввести регистрационные данные.

sshpass -p "password" scp -r /path/to/local/file remote_user@remote_host:/path/to/remote/file

Здесь:

  • -p - параметр для передачи пароля
  • "password" - само значение пароля

Если не хотите "светить" пароль в истории bash-запросов, тогда используйте код ниже.

sshpass -f "/путь/к/файлу-с-паролем" scp -r /path/to/local/file remote_user@remote_host:/path/to/remote/file

Здесь:

  • -f - параметр для указания пути к файлу, который содержит в себе пароль. После выполнения команды файл необходимо удалить из соображений безопасности.

Как установить SSHPASS

Ниже перечислены способы установки SSHPASS для различных ОС:

  • ubuntu/debian
    • apt install sshpass
  • centos/fedora
    • yum install sshpass
  • mac w/ macports
    • port install sshpass
  • mac w/ brew
    • brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master‌​/Library/Formula/ssh‌​pass.rb

Tags: SCP SSHPASS

Комментарии  

Рен
# Рен 26.06.2019 12:29
Спасибо за подробное описание, скажите, можно ли таким образом построить команду чтобы не вводить запрос пароля? Можно ли пароль указать сразу?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Павел А. Сафронов
# Павел А. Сафронов 26.06.2019 22:45
Во-первых, нужно отметить, что это небезопасно, т.к. передача пароля будет отражена в истории bash-запросов, либо, если вы забудете удалить парольный файл, пароль также может быть скомпрометирован. Тем не менее, мне кое-что удалось найти по Вашему вопросу и я добавил это в конец статьи с подзаголовком "Обновление от 26.06.2019". Пожалуйста, напишите, помогло ли дополнение статьи решить Вашу задачу. Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Sergey
# Sergey 07.09.2019 21:49
Все работает, спасибо
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору