ftp поддерживает put "|..." "remote-file.name"
команда для передачи данных по ftp-соединению. Есть ли что-то подобное для sftp?
В sftp я получаю следующую ошибку:
sftp 'jmw@backupsrv:/uploads'
sftp> put "| tar -cx /storage" "backup-2012-06-19--17-51.tgz"
stat | tar -cv /storage: No such file or directory
как указано выше, клиент sftp явно не выполняет команду.
Я хочу использовать команду pipe для прямого перенаправления файлового потока в sftp. (поскольку недостаточно места для создания файла резервной копии на том же диске перед его загрузкой на сервер sftp.)
Поскольку это первый результат, который вы найдете при поиске в Google по этому вопросу, и он еще не упоминался, я также добавлю решение, которое я нашел здесь:
для этого вы можете использовать реализацию curls sftp. Поскольку curl, вероятно, уже установлен во многих системах, это может быть предпочтительнее решения, использующего собственные клиенты.
пример использования:
pg_dump -d database | pigz -1 | curl -u username -T - sftp://sftpserver/folder/dbbackup.sql.gz
curl
использует ваш .ssh/known_hosts
файл для проверки ключа. Это может не сработать, если ваш ssh-клиент использует более новые стандарты шифрования, не поддерживаемые библиотекой, используемой в curl.
чтобы исправить это, вы можете добавить другие типы ключей в файл известных хостов, используя следующую команду:
ssh-keyscan sftpserver >> ~/.ssh/known_hosts
или вы можете отключить проверку ключа с помощью -k
флаг (хотя я бы не рекомендовал это)
Мне было очень интересно найти решение этой проблемы. Для этого требуется инструмент nc (netcat) на обеих машинах и SSH (SFTP не нужен).
В этом примере я назову машину, на которой есть данные, для которых необходимо создать резервную копию linux-a, и машину, которая должна получить резервную копию linux-b.
В linux-a пусть netcat прослушивает порт (я взял 2000) и перенаправляет его в файл. Он просто будет сидеть и ждать, пока что-то не пройдет через этот порт.
[kenny@linux-b /var/backups]$ nc -l 2000 > backup.tgz
На linux-b откройте ssh-туннель к linux-a, я снова использовал порт 2000. Это перенаправит все, что вы бросаете на TCP-порт 2000 на localhost, на TCP-порт 2000 на linux-a, где netcat прослушивает.
[kenny@linux-a /var/data]$ ssh -L 2000:localhost:2000 -CfN linux-b
Теперь создайте tar-архив, но отправьте вывод на стандартный вывод (используя -) и направьте его в gzip для некоторого сжатия. Теперь передайте это другому netcat, который отправляет его на localhost по TCP через порт 2000.
[kenny@linux-a /var/data]$ tar cf - important-data | gzip -fc | nc localhost 2000
Были сделаны! В linux-b netcat больше не слушает, и создается новый файл. Самое приятное то, что tar-архив никогда не помещался на жесткий диск linux-a.
[kenny@linux-b /var/backups]$ file backup.tgz
backup.tgz: gzip compressed data, from Unix, last modified: Thu Jul 5 13:48:03 2012
Я знаю, что это не совсем то, о чем вы просили в вопросе, но если у вас есть netcat, это жизнеспособное решение вашей проблемы.
Редактировать: Я забыл об одном: если вы будете следовать этим инструкциям, у вас все еще будет туннель SSH, плавающий в linux-a. Узнайте, что такое идентификатор процесса, и уничтожьте его.
[kenny@linux-a /var/data]$ ps -ef | grep "ssh -L"
kenny 5741 1 0 13:40 ? 00:00:00 ssh -L 2000:localhost:2000 -CfN linux-b
kenny 5940 3360 0 14:13 pts/1 00:00:00 grep --color=auto ssh -L
[kenny@linux-a /var/data]$ kill 5741
output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command'
это вариант, если у вашего удаленного пользователя есть действующая оболочка.
voretaq7 отметил, что клиент sftp не поддерживает передачу данных по конвейеру для пользователей, которым разрешено использовать sftp только для подключения к серверу.
К счастью, есть libssh2, поддерживающая sftp. поэтому нам просто нужно 2 других клиента, использующих libssh2, которые я вызвал:
исходный код можно найти по следующему URL-адресу: http://www.qxs.ch/2012/07/05/sftp-upload-tool/
так как я не настолько опытен в программировании libssh2, я рад любой обратной связи с исходным кодом.