Перенос файлов между серверами напрямую по 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 - путь к конечной папке сервера, куда будут загружены файлы.
Предостерегая вас от двойной работы и вопросов:
- пути к копируемым папкам/файлам нужно вводить абсолютные. Это значит, если, допустим, у вас есть аккаунт у хостинг-провайдера и называется он vaspupkin1, вероятней всего, что он находится в папке наряду с остальными аккаунтами пользователей и может иметь полный путь от корня сервера такой: /home/w/vaspupkin1, в то время как файлы сайта могут лежать в папке /home/w/vaspupkin1/public_html . Поэтому, чтобы скопировать папку с сайтом на другой сервер, мы должны в первой части команды scp после параметра -r ввести следующее: /home/w/vaspupkin1/public_html, в то время, когда вы, подключаясь к своему аккаунту по FTP, сразу попадаете в папку /vaspupkin1, что является относительным, а не абсолютным путем.
- при копировании папки описанным выше образом на удаленном сервере создается эта же папка. Т.е. когда вы, копируя папку /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/sshpass.rb