Armazene a saída do comando no recurso SFTP

Armazene a saída do comando no recurso SFTP

Eu só queria criar um tar ball e armazená-lo apenas em um recurso SFTP. Como sou paranóico com a corrupção de dados, geralmente armazeno os sha256sums das minhas bolas tar com eles, se for algo em que quero poder confiar, e calculo-os ao gerar os arquivos e depois de terem sido escritos, lendo-os de a mídia de armazenamento em que estão armazenados.

Presumi que isso fosse bastante simples, então digitei este comando em:

tar --exclude='./somefolder' -zc . | tee "sftp://mydomain.ending/storage/location/on/server/sth.tar" | sha256sum

Também tentei o que o Nautilus usa para seus terminais remotos:

tar --exclude='./somefolder' -zc . | tee ":/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar" | sha256sum

No entanto, as saídas foram:

tee: 'sftp://mydomain.ending/storage/location/on/server/sth.tar': No such file or directory

e

tee: ':/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar': No such file or directory

respectivamente.

Como faço para armazenar a bola de alcatrão sem armazená-la primeiro localmente? De preferência sem montar primeiro o recurso remoto em alguma pasta para que possa ser usado facilmente.

Eu uso Ubuntu 16.04 (com Linux 4.4.0).

Responder1

Sem montagens sofisticadas de gvfs ou sshfs, você precisa usar um cliente SFTP. Eu escolho lftp>=4.7 porque funciona com tubos FIFO ( scpe sftpnão funciona).

Isso funciona bashno Linux:

tar --exclude='./somefolder' -zc . \
 | tee >(lftp -c 'connect sftp://user:pass@server/path/ ;put /dev/stdin -o sth.tar.gz;') \
 | sha256sum

Alternativamente, usando sshcliente (colchetes externos necessários para autenticação de senha interativa):

(tar --exclude='./somefolder' -zc . \
 | tee >(ssh user@server "cat > /path/sth.tar.gz") \
 | sha256sum)

Observe que tee'so argumento também parece um pouco exótico, mas esta é uma mágica não portátil bashpara evitar mkfifocomandos adicionais, explicados em man bash:

Substituição de Processo

A substituição de processo é suportada em sistemas que suportam pipes nomeados (FIFOs) ou o método /dev/fd de nomear arquivos abertos. Assume a forma de <(lista) ou >(lista). A lista de processos é executada com sua entrada ou saída conectada a um FIFO ou algum arquivo em /dev/fd. O nome deste arquivo é passado como argumento para o comando atual como resultado da expansão. Se o formulário >(list) for usado, escrever no arquivo fornecerá entrada para a lista. Se a forma <(list) for usada, o arquivo passado como argumento deverá ser lido para obter a saída da lista.

Responder2

O Nautilus usa gvfspara montar locais de armazenamento remoto, como o servidor SFTP da sua pergunta. Isso permite tratar o servidor remoto como se fosse parte do seu sistema de arquivos local. O caminho em que ele é montado geralmente é

/run/user/<your uid>/gvfs/<server specification>/<path>

Tenho quase certeza de que o prefixo é sempre

/run/user/<your uid>

para que você possa encontrar esse ponto de montagem lsou Tabpassar por esse diretório.

Depois de encontrar esse ponto de montagem, você pode usá tee-lo normalmente (com quebras de linha adicionadas para maior clareza):

tar --exclude='./somefolder' -zc .  \
| tee "/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar"  \
| sha256sum

Alternativamente, você pode evitar uma montagem GVFS e ainda evitar a substituição de processo não portátil usando SSH em vez de SFTP:

tar --exclude='./somefolder' -zc .  \
| ssh mydomain.ending 'tee "/storage/location/on/server/sth.tar"' 2>/dev/null  \
| sha256sum

Infelizmente, sftpo programa não permite enviar arquivos para um host remoto por meio de uma única linha de comando, apenas recuperá-los.

Como aponta @rudimeier, o sshmétodo acima carregae downloadso arquivo para evitar armazená-lo localmente. Se você preferir não baixá-lo novamente, talvez seja melhor fazer isso sha256sumremotamente:

tar --exclude='./somefolder' -zc .  \
| ssh mydomain.ending 'tee "/storage/location/on/server/sth.tar" | sha256sum' 2>/dev/null

informação relacionada