Отправитель и получатель будут передавать файлы по ssh по запросу?

StackOverflow https://stackoverflow.com/questions/515726

Вопрос

Я создал программу, которая перебирает множество файлов и вызывает для некоторых из них:

scp <file> user@host:<remotefile>

Однако в моем случае могут быть тысячи небольших файлов, которые необходимо перенести, и scp открывает новое ssh-соединение для каждого из них, что сопряжено с довольно большими накладными расходами.

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

В идеале, я ищу комбинацию какой-либо программы-отправителя и программы-получателя, такую, чтобы я мог запустить один процесс (1) в начале:

ssh user@host receiverprogram

И для каждого файла я вызываю команду (2):

senderprogram <file> <remotefile>

и передайте выходные данные (2) на вход (1), и это приведет к передаче файла.В конце концов, я могу просто отправить процессу (1) некоторый сигнал для завершения.

Предпочтительно, чтобы программы-отправители и программы-получатели были программами на языке Си с открытым исходным кодом для Unix.Они могут взаимодействовать, используя сокет вместо канала, или любое другое творческое решение.

Тем не менее, это важное ограничение что каждый файл передается в тот момент, когда я выполняю итерацию по нему:недопустимо собирать список файлов, а затем вызывать один экземпляр scp чтобы в конце перенести все файлы сразу.Кроме того, у меня есть только простой доступ оболочки к принимающему хосту.

Обновить: Я нашел решение проблемы накладных расходов на подключение, используя функции мультиплексирования ssh, смотрите мой собственный ответ ниже.Тем не менее, я начинаю розыгрыш призов, потому что мне любопытно узнать, существует ли программа-отправитель / получатель, как я описываю здесь.Кажется, должно существовать что-то, что можно использовать, напримерxmodem/ymodem/zmodem?

Это было полезно?

Решение

Этот способ сработал бы, и для других вещей этот общий подход более или менее верен.

(
iterate over file list
  for each matching file
   echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud

Другие советы

Я нашел решение с другой стороны.С тех пор как версия 3.9, Поддержка OpenSSH мультиплексирование сеансов:одно соединение может выполнять несколько сеансов входа в систему или передачи файлов.Это позволяет избежать затрат на настройку каждого подключения.

В случае с этим вопросом я могу сначала открыть соединение с помощью настройки главного элемента управления (-M) с розеткой (-S) в определенном месте.Мне не нужен сеанс (-N).

ssh user@host -M -S /tmp/%r@%h:%p -N

Далее, я могу вызвать scp для каждого файла и проинструктируйте его использовать один и тот же сокет:

scp -o 'ControlPath /tmp/%r@%h:%p' <file> user@host:<remotefile>

Эта команда начинает копирование практически мгновенно!

Вы также можете использовать управляющий сокет для обычных ssh-подключений, которые затем немедленно откроются:

ssh user@host -S /tmp/%r@%h:%p

Если управляющий разъем больше недоступен (например,потому что вы убили мастера), это возвращает к обычному соединению.Более подробная информация доступна в эта статья.

Возможно, сработает использовать sftp вместо scp и перевести его в пакетный режим.Сделайте файл пакетной команды каналом или доменным сокетом UNIX и передавайте в него команды по мере их выполнения.

Безопасность при этом может быть немного сложной на стороне клиента.

Вы пробовали sshfs?Ты мог бы:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

Где

  • /remote_dir был ли каталог, в который вы хотите отправить файлы, в системе, в которую вы загружаетесь
  • /mnt/local_dir это было местное местоположение горы

С помощью этой настройки вы можете просто cp файл в local_dir и это было бы отправлено по почте sftp Для remote_host в своем remote_dir

Обратите внимание, что существует одно соединение, поэтому накладные расходы невелики

Возможно, вам придется использовать этот флаг -o ServerAliveInterval=15 для поддержания неопределенное соединение

Вам нужно будет иметь fuse установлен локально и поддерживает SSH-сервер (и настроен для него). sftp

Может быть, вы ищете это:ЗССШ

zssh (Zmodem SSH) - это программа для интерактивной передачи файлов на удаленный компьютер при использовании защищенной оболочки (ssh).Предполагается, что он станет удобной альтернативой scp, позволяющей передавать файлы без необходимости открывать другой сеанс и повторной аутентификации.

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

Если у вас нет всех файлов в одном месте, пожалуйста, предоставьте дополнительную информацию о том, чего вы хотите достичь и почему вы не можете упаковать все файлы в архив и отправить его по почте.Почему так важно, чтобы каждый файл отправлялся немедленно?Было бы нормально, если бы файл был отправлен с небольшой задержкой (например, когда накопилось данных на 4 тыс.)?

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

#!/bin/ksh
# this is receiverprogram

while true
do
  typeset -i length
  read filename  # read filename sent by sender below
  read size      # read size of file sent
  read -N $size contents  # read all the bytes of the file
  print -n "$contents" > "$filename"
done

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

mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection

Затем, чтобы отправить файл, я бы попробовал этот скрипт

#!/bin/ksh
# this is senderprogram

FIFO=$HOME/my-connection

localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO

Если размер файла большой, вы, вероятно, не захотите читать его за один раз, поэтому что-то порядка

BUFSIZ=8192

rm -f "$filename"
while ((size >= BUFSIZ)); do
  read -N $BUFSIZE buffer
  print -n "$buffer" >> "$filename"
  size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"

В конце концов вам захочется расширить скрипт, чтобы вы могли пройти через chmod и chgrp команды.Поскольку вы доверяете коду отправки, вероятно, проще всего структурировать это так, чтобы получатель просто вызывал shell eval в каждой строке затем отправляйте что-то вроде

print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO

а затем определите локальную функцию read_and_copy_bytes.Правильно сформулировать цитирование - непростая задача, но в остальном все должно быть просто.

Конечно, ничего из этого не было проверено!Но я надеюсь, что это натолкнет вас на несколько полезных идей.

Похоже, это работа для вас?Передайте его выходные данные в ssh, а с другой стороны, передайте выходные данные ssh обратно в tar.

Я думаю, что рабочий стол GNOME использует одно SSH-соединение при доступе к общему ресурсу через SFTP (SSH).Я предполагаю, что это то, что происходит, потому что я вижу один SSH-процесс, когда я получаю доступ к удаленному общему ресурсу таким образом.Так что, если это правда, вы должны иметь возможность использовать ту же программу для этой цели.

Новая версия GNOME использовала GVFS через ДЖИО для того, чтобы выполнять все виды операций ввода-вывода через разные серверные части.Пакет Ubuntu gvfs-bin предоставляет различные утилиты командной строки, которые позволяют вам манипулировать серверными программами из командной строки.

Сначала вам нужно будет смонтировать вашу SSH-папку:

gvfs-крепление sftp://user@host/

И затем вы можете использовать gvfs-copy для копирования ваших файлов.Я думаю, что все передачи файлов будут выполняться через один SSH-процесс.Вы даже можете использовать ps, чтобы увидеть, какой процесс используется.

Если вы чувствуете себя более предприимчивым, вы даже можете написать свою собственную программу на C или на каком-нибудь другом языке высокого уровня, который предоставляет API для GIO.

Одним из вариантов является Раковина является ли реализация SSH-клиента и сервера написанной на Python с использованием Совмещенный рамки.Вы могли бы использовать его для написания инструмента, который принимает запросы по какому-либо другому протоколу (HTTP или доменные сокеты Unix, FTP, SSH или что-то еще) и запускает передачу файлов по длительно работающему SSH-соединению.На самом деле, у меня есть несколько готовых программ, которые используют этот метод, чтобы избежать нескольких настроек SSH-соединения.

Там был здесь очень похожий вопрос пару недель назад.Тот Самый принятый ответ предложил открыть туннель при подключении по ssh к удаленной машине и использовать этот туннель для передачи scp.

Возможно , CurlFTPFS ( кудряшки ) возможно, это подходящее решение для вас.

Похоже, что он просто подключает папку внешнего компьютера к вашему компьютеру через SFTP.Как только это будет сделано, вы сможете использовать свой обычный cp команды, и все будет сделано надежно.

К сожалению, я не смог протестировать это сам, но дайте мне знать, если у вас это сработает!

Правка 1: Мне удалось скачать и протестировать его.Как я и опасался, для этого требуется, чтобы у клиента был FTP-сервер. Однако, Я нашел другую программу, которая имеет точно такую же концепцию, что и то, что вы ищете. sshfs позволяет вам подключаться к вашему клиентскому компьютеру без использования какого-либо специального сервера.После того как вы смонтировали одну из их папок, вы можете использовать свой обычный cp команды для перемещения любых файлов, которые вам нужны, в more.Как только вы закончите, это должно стать вопросом улыбки umount /path/to/mounted/folder.Дайте мне знать, как это работает!

rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder

Это позволит использовать SSH для передачи файлов не медленным способом

Сделайте это проще, напишите небольшой скрипт-оболочку, который делает что-то вроде этого.

  1. проверьте файлы
  2. отправьте tar-файл
  3. унтар на другой стороне

Что - то вроде этого:

  1. файлы tar -cvzf test.tgz ....
  2. тест на scp.tgz user@other.site.com :.
  3. ssh user@other.site.com тест tar -xzvf.tgz

/Йохан

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top