Estou tentando concatenar vários arquivos/fluxos de entrada em um fluxo (usando o comando imaginário stream-cat
), canalizar esse fluxo para dentro ssh
e no host remoto, separá-lo de volta em arquivos/fluxos individuais ( stream-sep
), como neste exemplo, que é para demonstração propósitos apenas:
stream-cat <( zfs send tank/vm@snapshot ) somefile.txt | ssh user@host "stream-sep >( zfs receive tank/vm@snapshot ) somefile.txt"
Explicação do exemplo: zfs send
gera um grande fluxo de dados cujo tamanho não é conhecido antecipadamente (é por isso que tar
não pode lidar com isso). Esse fluxo de dados é concatenado com o conteúdo de um arquivo regular somefile.txt
. O fluxo resultante é canalizado para ssh
, onde é separado novamente. O primeiro fluxo é canalizado para zfs receive
, enquanto o segundo é gravado em um arquivo regular.
Tal programa deve ser simples de implementar lendo fluxos não pesquisáveis em blocos e sempre escrevendo o tamanho do bloco seguido pelos dados, até que o final do fluxo seja alcançado. A sobrecarga seria mínima.
Esse programa já existe?
O que você está descrevendo é multiplexação ; algo que requer um protocolo (ou seja, uma especificação formal sobre como lidar com os dados).
Há muitas abordagens para isso. Por exemplo, você notará que seu computador pode perfeitamente baixar vários arquivos ao mesmo tempo via HTTP – até mesmo do mesmo servidor. Esse recurso é trazido a você principalmente pelo TCP, que, como protocolo de transporte, permite que diferentes fluxos sejam enviados e "desmontados" na extremidade receptora.
Portanto, o TCP já oferece essa funcionalidade e você pode simplesmente iniciar duas conexões SSH simultâneas e usá-la!
Claro, em vez do levemente deselegante
cat somefile.txt | ssh … > somefile.txt
, você provavelmente usaria apenasscp somefile.txt user@host:somefile.txt
(que usa SSH sob o capô, mas não faz uma conexão shell, mas usa a camada SCP integrada no SSH para copiar o arquivo).Você pode tornar o estabelecimento de conexão para a segunda conexão mais rápido adicionando o seguinte ao seu
~/.ssh/config
arquivo:Isso dirá ao SSH para tentar reutilizar a única sessão SSH para enviar vários fluxos criptografados ao mesmo tempo (isso funciona com qualquer combinação de
scp
essh
também).Implementações brutas dessas
stream-cat
,stream-sep
poderiam ser facilmente escritas emperl
:ou o mesmo que
#! /bin/sh -
scripts em vez desh
funções.(tratamento de erro deixado como exercício para o leitor :-).
stream-cat
envia registros de até 32767 bytes grandes prefixados por umn
short codificado em rede (big-endian) cujo bit mais baixo indica se é o início de um novo fluxo (0) ou a continuação, e os bits restantes são o tamanho.E então, por exemplo:
Então no seu caso:
Um caso raro em que a forma insegura de
open
(aqui também usada por<>
como usada por-n
), que permite<file
abrir>file
arquivos no modo somente leitura ou somente gravação ou|cmd
canalizarcmd|
para/de um comando é realmente útil.Usando essas escalas
|cmd
/cmd|
melhor do que o seu<(cmd)
/>(cmd)
como apenas um está aberto por vez, para que você possa enviar milhares de fluxos separados sem problemas.