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

Как правильно заархивировать директорию в tar.gz на сервере 1 и передать ее на сервер 2 без промежуточного хранения на сервере 1, учитывая нехватку дискового пространства? 

Я использую команду, которая направляет вывод tar в стандартный поток (stdout) и перенаправляет его через ssh, но сталкиваюсь с проблемами. Во-первых, вывод после выполнения tar все еще отображается в терминале, и во-вторых, при тестировании с файлом размером в несколько десятков гигабайт на сервер 2 приходит файл размером только в несколько мегабайт. 

Вот моя команда:
<pre><code>tar -czf - /home/target | sshpass -p 'pwd' ssh -p 23 [email protected] 'cat &gt; /home/backups/destination.tar.gz'</code></pre> 

Как можно это реализовать корректно? Оба сервера работают под управлением Linux, и я ищу скрипт на bash, который не будет выводить содержимое tar в терминал. Пароль для ssh должен передаваться через sshpass. Также можно использовать rsync или scp вместо ssh.
  • 10 октября 2024 г. 18:34
Ответы на вопрос 10
Ваша команда в целом правильная, но, скорее всего, вы сталкиваетесь с проблемами из-за некорректной обработки вывода. Попробуйте использовать `-f` для подавления вывода в терминал и отключить вывод ошибок, чтобы он не отображался. Также убедитесь, что `sshpass` правильно работает с вашим паролем.

Вот откорректированная версия вашей команды:

```bash
tar -czf - /home/target | sshpass -p 'pwd' ssh -p 23 [email protected] 'cat > /home/backups/destination.tar.gz' 2>/dev/null
```

Краткое объяснение компонентов:

- `tar -czf - /home/target`: создаёт архив в формате gzipped tar и выводит его в стандартный поток (stdout).
- `|`: передаёт вывод `tar` через конвейер в следующую команду.
- `sshpass -p 'pwd'`: передаёт пароль для SSH.
- `ssh -p 23 [email protected] 'cat > /home/backups/destination.tar.gz'`: использует SSH для подключения к серверу и перенаправления содержимого в файл `destination.tar.gz`.
- `2>/dev/null`: подавляет любой вывод ошибок, чтобы они не показывались в терминале.

### Альтернативное решение с использованием `pv`

Ещё одним вариантом, который позволяет отслеживать процесс передачи и подавлять вывод, является использование утилиты `pv`. Она показывает прогресс передачи и позволяет контролировать ввод/вывод:

```bash
tar -czf - /home/target | pv | sshpass -p 'pwd' ssh -p 23 [email protected] 'cat > /home/backups/destination.tar.gz'
```

Это будет отображать процент передачи данных и общую скорость, при этом не выводя лишней информации в терминал.

### Проверка на сервере 2

После завершения передачи убедитесь, что файл корректно создан на сервере 2, с помощью команды `ls -lh /home/backups/destination.tar.gz` и `tar -tvf /home/backups/destination.tar.gz`, чтобы проверить содержимое архива. 

### Использование `rsync`

Если вы хотите скопировать каталог, не создавая промежуточные файлы, `rsync` также может подойти. Однако для вашего случая с архивированием скорее подойдет `tar`. Использование `rsync` лучше для прямого копирования директорий:

```bash
sshpass -p 'pwd' rsync -avz -e "ssh -p 23" /home/target/ [email protected]:/home/backups/
```

Но учтите, что `rsync` не сжимает файлы, как делает `tar`. Пользуйтесь `tar` для сжатия, если это критично.
tar -cz /home/target | sshpass -p 'pwd' ssh -p 23 [email protected] 'cat > /home/backups/destination.tar.gz'


Все должно так работать. Если у вас ошибка от tar, то может это не stdout а stderr?
Приведите текст что там не так. Файл в конечно счете правильный выходит?
tar -cz /home/target | sshpass -p 'pwd' ssh -p 23 [email protected] 'cd /unpack/me/here && tar -zx'
А как насчёт scp -C ? Там, правда, gzip-сжатие.
tar cvfz - --ignore-failed-read  --directory /var/www/3dpaneli.ru/web . |ssh [email protected] cd /tmp/test/aa;tar xvfz -"
tar -cz /home/target | sshpass -p 'pwd' ssh -p 23 [email protected] 'cat > /home/backups/destination.tar.gz'


Все должно так работать. Если у вас ошибка от tar, то может это не stdout а stderr?
Приведите текст что там не так. Файл в конечно счете правильный выходит?
tar -cz /home/target | sshpass -p 'pwd' ssh -p 23 [email protected] 'cd /unpack/me/here && tar -zx'
А как насчёт scp -C ? Там, правда, gzip-сжатие.
tar cvfz - --ignore-failed-read  --directory /var/www/3dpaneli.ru/web . |ssh [email protected] cd /tmp/test/aa;tar xvfz -"
подключить том сервера 2 на сервере 1 как локальный через sshfs и скопировать все обычным rsync'ом...
Похожие вопросы