
Ich wollte nur einen Tarball erstellen und ihn nur auf einer SFTP-Ressource speichern. Da ich Angst vor Datenbeschädigungen habe, speichere ich normalerweise die SHA256-Summen meiner Tarballs mit ihnen, wenn ich mich darauf verlassen möchte, und berechne sie sowohl beim Generieren der Archive als auch nach dem Schreiben, indem ich sie von den Speichermedien lese, auf denen sie gespeichert sind.
Ich ging davon aus, dass dies ziemlich unkompliziert sei, also gab ich diesen Befehl ein:
tar --exclude='./somefolder' -zc . | tee "sftp://mydomain.ending/storage/location/on/server/sth.tar" | sha256sum
Ich habe auch ausprobiert, was Nautilus für seine Remote-Terminals verwendet:
tar --exclude='./somefolder' -zc . | tee ":/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar" | sha256sum
Die Ergebnisse waren jedoch:
tee: 'sftp://mydomain.ending/storage/location/on/server/sth.tar': No such file or directory
Und
tee: ':/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar': No such file or directory
jeweils.
Wie speichere ich den Tarball dort, ohne ihn vorher lokal zu speichern? Am besten ohne die Remote-Ressource vorher in einem Ordner zu mounten, damit sie einfach verwendet werden kann.
Ich verwende Ubuntu 16.04 (mit Linux 4.4.0).
Antwort1
Ohne schicke GVFS- oder SSHFS-Mounts müssen Sie einen SFTP-Client verwenden. Ich wähle lftp
>=4.7, weil es mit FIFO-Pipes funktioniert ( scp
und sftp
nicht).
Dies funktioniert bash
unter Linux mit:
tar --exclude='./somefolder' -zc . \
| tee >(lftp -c 'connect sftp://user:pass@server/path/ ;put /dev/stdin -o sth.tar.gz;') \
| sha256sum
Alternativ mit ssh
Client (äußere Klammern für interaktive Passwortauthentifizierung erforderlich):
(tar --exclude='./somefolder' -zc . \
| tee >(ssh user@server "cat > /path/sth.tar.gz") \
| sha256sum)
Beachten Sie, dass tee's
das Argument auch etwas exotisch aussieht, aber dies ist nicht portable bash
Magie, um zusätzliche mkfifo
Befehle zu vermeiden, erklärt in man bash
:
Prozesssubstitution
Prozesssubstitution wird auf Systemen unterstützt, die benannte Pipes (FIFOs) oder die /dev/fd-Methode zum Benennen offener Dateien unterstützen. Sie hat die Form <(Liste) oder >(Liste). Der Prozess list wird mit seiner Eingabe oder Ausgabe ausgeführt, die mit einer FIFO oder einer Datei in /dev/fd verbunden ist. Der Name dieser Datei wird als Ergebnis der Erweiterung als Argument an den aktuellen Befehl übergeben. Wenn die Form >(Liste) verwendet wird, liefert das Schreiben in die Datei eine Eingabe für list. Wenn die Form <(Liste) verwendet wird, sollte die als Argument übergebene Datei gelesen werden, um die Ausgabe von list zu erhalten.
Antwort2
Nautilus verwendet gvfs
zum Mounten von Remote-Speicherorten, wie z. B. dem SFTP-Server in Ihrer Frage. Dadurch können Sie den Remote-Server so behandeln, als wäre er Teil Ihres lokalen Dateisystems. Der Pfad, in den er gemountet wird, ist normalerweise
/run/user/<your uid>/gvfs/<server specification>/<path>
Ich bin ziemlich sicher, dass das Präfix immer ist
/run/user/<your uid>
Sie können diesen Einhängepunkt also finden, indem Sie dieses Verzeichnis mit ls
oder Tab- durchsuchen.
Sobald Sie diesen Einhängepunkt gefunden haben, können Sie ihn tee
wie gewohnt verwenden (mit Zeilenumbrüchen zur besseren Übersicht):
tar --exclude='./somefolder' -zc . \
| tee "/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar" \
| sha256sum
Alternativ können Sie eine GVFS-Einbindung und dennoch die nicht portable Prozessersetzung vermeiden, indem Sie SSH anstelle von SFTP verwenden:
tar --exclude='./somefolder' -zc . \
| ssh mydomain.ending 'tee "/storage/location/on/server/sth.tar"' 2>/dev/null \
| sha256sum
Leider sftp
erlaubt das Programm nicht, Dateien über eine einzige Befehlszeile auf einen Remote-Host zu übertragen, sondern nur, sie abzurufen.
Wie @rudimeier anmerkt, ssh
lädt die obige Methodeund Downloadsdie Datei, um zu vermeiden, dass sie lokal gespeichert wird. Wenn Sie sie nicht erneut herunterladen möchten, ist es möglicherweise besser, dies sha256sum
remote zu tun:
tar --exclude='./somefolder' -zc . \
| ssh mydomain.ending 'tee "/storage/location/on/server/sth.tar" | sha256sum' 2>/dev/null