Almacenar la salida del comando en el recurso SFTP

Almacenar la salida del comando en el recurso SFTP

Solo quería crear una bola de alquitrán y almacenarla únicamente en un recurso SFTP. Como soy paranoico con la corrupción de datos, normalmente almaceno las sumas sha256 de mis bolas tar con ellas si es algo en lo que quiero poder confiar, y las calculo tanto al generar los archivos como después de haberlos escrito leyéndolos desde el medio de almacenamiento en el que están almacenados.

Supuse que esto era bastante sencillo, así que escribí este comando en:

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

También probé lo que usa Nautilus para sus terminales remotos:

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

Sin embargo, los resultados fueron:

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

y

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

respectivamente.

¿Cómo almaceno la bola de alquitrán allí sin almacenarla primero localmente? Preferiblemente sin montar primero el recurso remoto en alguna carpeta para que pueda usarse fácilmente.

Yo uso Ubuntu 16.04 (con Linux 4.4.0).

Respuesta1

Sin montajes sofisticados de gvfs o sshfs, necesita usar un cliente sftp. Elijo lftp>=4.7 porque funciona con tuberías FIFO ( scpy sftpno lo hace).

Esto funciona bashen Linux:

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

Alternativamente, use sshel cliente (se necesitan corchetes externos para la autenticación de contraseña interactiva):

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

Tenga en cuenta tee'sque el argumento también parece un poco exótico, pero se trata de magia no portátil bashpara evitar mkfifocomandos adicionales, como se explica en man bash:

Sustitución de procesos

La sustitución de procesos se admite en sistemas que admiten canalizaciones con nombre (FIFO) o el método /dev/fd para nombrar archivos abiertos. Toma la forma de <(lista) o >(lista). La lista de procesos se ejecuta con su entrada o salida conectada a un FIFO o algún archivo en /dev/fd. El nombre de este archivo se pasa como argumento al comando actual como resultado de la expansión. Si se utiliza el formulario >(lista), escribir en el archivo proporcionará información para la lista. Si se utiliza el formato <(lista), el archivo pasado como argumento debe leerse para obtener el resultado de la lista.

Respuesta2

Nautilus utiliza gvfspara montar ubicaciones de almacenamiento remotas, como el servidor SFTP en su pregunta. Esto le permite tratar el servidor remoto como si fuera parte de su sistema de archivos local. El camino al que asciende suele ser

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

Estoy bastante seguro de que el prefijo es siempre

/run/user/<your uid>

para que pueda encontrar este punto de montaje navegando lso Tabnavegando por ese directorio.

Una vez que haya encontrado este punto de montaje, puede usarlo teecomo lo haría normalmente (con saltos de línea agregados para mayor claridad):

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

Alternativamente, puede evitar un montaje GVFS y aun así evitar la sustitución de procesos no portátiles usando SSH en lugar de SFTP:

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

Desafortunadamente, sftpel programa no permite enviar archivos a un host remoto a través de una única línea de comando, solo recuperarlos.

Como señala @rudimeier, el sshmétodo anterior cargay descargasel archivo para evitar almacenarlo localmente. Si prefieres no volver a descargarlo, sería mejor hacerlo sha256sumde forma remota:

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

información relacionada