Ich beabsichtige, vollständige und inkrementelle Sicherungen meiner btrfs-Subvolumes an einen Bandarchivierungsdienst zu übertragen. Der Dienst macht FTP- und SSH-Endpunkte verfügbar. Wenn ich beliebige Befehle auf dem SSH-Endpunkt ausführen dürfe, würde ich Folgendes tun, um eine Teilsicherung durchzuführen:
btrfs send -p $LAST_SUBVOLUME $NEXT_SUBVOLUME | compress | encrypt |
ssh -p $PORT $USER@$ENDPOINT "cat > $SUBVOLUME.$YYYYMMDD.btrfs.bz2.gpg"
Das darf ich aber nicht:
$ ssh -p $PORT $USER@$ENDPOINT
Last login: Mon Jan 3 01:23:45 2067 from 123.456.789.123
This account is restricted by rssh.
Allowed commands: scp sftp rsync
If you believe this is in error, please contact your system administrator.
Connection to some.remote.endpoint closed.
Stattdessen wollte ich das SCP-Protokoll für die Übertragung verwenden. Meine scp
Binärdatei weigert sich jedoch, eine Named Pipe zu übertragen:
$ scp -P $PORT <(btrfs send -p $LAST_SUBVOLUME $NEXT_SUBVOLUME | compress | encrypt) \
$USER@$ENDPOINT:$SUBVOLUME.$YYYYMMDD.btrfs.bz2.gpg
/dev/fd/63: not a regular file
Die Ironie ist, dass man anscheinend BEARBEITEN (03.06.2017): Dies war eine falsche Beobachtung. Wie Kenster feststellt, können mit dem SCP-Protokoll keine Dateien unbekannter Größe gesendet werden.scp
einmal das Richtige getan hat . Ich nehme an, nicht jeder hat gedacht, dass das Übertragen von Named Pipes vernünftig / nützlich sein könnte.
UPDATE (2017-06-04): Ich habe auch versucht, die Daten mit dem SFTP-Protokoll zu übertragen. Offensichtlich erlaubt das FTP-Protokoll das Senden von Dateien unbekannter Größe, was durch die Unterstützung von Piping-Daten in den Binärdateien ftp
( Link ) und ncftpput
( Link , Abschnitt Beschreibung, letzter Absatz) belegt wird. Ich fand keine solche Unterstützung in den SFTP-Clients, die ich ausprobiert habe ( sftp
, lftp
). Dies könnte ein Hinweis darauf sein, dass SFTP (im Gegensatz zu FTP) das Senden von Dateien unbekannter Größe nicht unterstützt (anders als ich dachte, ist SFTP nicht nur über SSH mit FTP verbunden) es ist ein anderes Protokoll).
UPDATE (2017-06-05): Gemäß dem Internet-Entwurf ( Link ) des SFTP-Protokolls, Version 3 , muss jedes Paket auf Anwendungsebene die Nutzdatenlänge vor der Nutzdaten angeben ( Link , Abschnitt 3). SFTP unterstützt jedoch Suchvorgänge in der geschriebenen Datei ( Link , Abschnitt 6.4) mit expliziter Unterstützung für Schreibvorgänge über das aktuelle Dateiende hinaus. Daher sollte es möglich sein, einen kleinen Puffer auf der Clientseite zu verwenden und eine Datei unbekannter Größe in kleinen, bekannt großen Blöcken zu senden:
#!/bin/bash
# <Exchange SSH_FXP_INIT requests.>
# <Send an SSH_FXP_OPEN request.>
CHUNK_SIZE=32768
OFFSET=0
IFS=''; while read -r -N $CHUNK_SIZE CHUNK; do
ACTUAL_SIZE=`cat <<<"$CHUNK" | head -c -1 | wc -c`
# <Send an SSH_FXP_WRITE request with payload $CHUNK of size
# $ACTUAL_SIZE at offset $OFFSET.>
OFFSET=$(($OFFSET+$ACTUAL_SIZE))
done < <(command)
# <Send an SSH_FXP_CLOSE request.>
Es wäre jedoch sehr schmerzhaft, die Kommunikation manuell über die Shell durchzuführen. Ich suche einen SFTP-Client, der diese Art von Funktionalität verfügbar macht.
scp
früher Rohre gehandhabt wurden. Der Fehlerbericht, den Sie verknüpfen, zeigt, dass er auf unbestimmte Zeit an Pipes hängt. jetzt warnt es dich stattdessen. Das klingt nach einer besseren Fehlerberichterstattung, nicht nach einer Änderung des zugrunde liegenden Verhaltens.Antworten:
lftp
4.6.1 und neuere Versionen sollten dazu in der Lage sein: https://github.com/lavv17/lftp/issues/104Leider funktioniert der in der verlinkten Ausgabe vorgeschlagene Befehl nicht, ein leicht modifizierter Befehl jedoch:
Aufgrund eines Fehlers müssen Sie etwas in das Kennwortfeld eingeben, wenn Sie einen SSH-Agenten verwenden. Aber jede zufällige Zeichenfolge reicht aus.
Dieser Befehl liest aus
/dev/stdin
. Wenn Sie eine andere Named Pipe verwenden müssen, sollte das meiner Meinung nach auch funktionieren - wenn nicht, können Sie das immercat named-pipe | lftp ...
.Ich habe
lftp
mit einem Upload von> 100 GB ohne Probleme getestet .rclone
unterstützt auch SFTP und sollte in der Lage sein, von einer Pipe-Eingabe mit demrcat
Befehl hochzuladen , da dies in 1.38 (nächste Version) veröffentlicht wird.quelle
put: /dev/stdin: cannot seek on data source
Fehler mit denlftp
vom Debian-Projekt veröffentlichten Binärdateien 4.7.4 und 4.8.1. Ich muss überprüfen, ob dies eine Regression in der Quelle ist oder ob dies ein Build-Problem ist. Ich werde dies zur akzeptierten Antwort machen, nachdem ich es geschafft habe, Ihre Ergebnisse zu reproduzieren.lftp
auf Debian Stretch getestet habe . Paketversion4.7.4-1
. LFTP-Version 4.7.4, Readline 7.0, GnuTLS 3.5.8, zlib 1.2.8. Der vollständige Befehl , den ich lief ein Rohr aus aufgenommen ,openssl enc
obwohlpv
und dann inlftp
.lftp
die obige nicht hilfreiche Fehlermeldung ausgegeben wurde . Vielen Dank für den Rat, es wird sehr geschätzt!zfs send | compress | encrypt | upload
) - es war tatsächlich Ihre Recherche, die mich davon überzeugt hat, den SFTP-Pfad und nicht SCP / rsync zu wählen. Vielen Dank für eine sehr gut geschriebene Frage (und Kenster für seine Analyse von SCP / SFTP). Ist Ihre Gegenstelle aus Neugier auch C14?SCP eignet sich nicht für Ihren Zweck. Das SCP-Protokoll unterstützt nicht das Senden eines Datenstroms unbekannter Größe an das ferne System, um als Datei gespeichert zu werden. Die SCP-Protokollnachricht zum Senden einer Datei erfordert, dass die Größe der Datei zuerst gesendet wird, gefolgt von den Bytes, aus denen die Datei besteht. Bei einem Stream von Bytes, die aus einer Pipe gelesen werden, würden Sie normalerweise nicht wissen, wie viele Bytes die Pipe produzieren wird, sodass es keine Möglichkeit gibt, eine SCP-Protokollnachricht mit der richtigen Größe zu senden.
(Die einzigen Online-Beschreibungen des SCP-Protokolls, die ich finden konnte, sind hier und hier . Konzentrieren Sie sich auf die Beschreibung der "C" -Meldung.)
Das SFTP-Protokoll kann für solche Dinge verwendet werden. Soweit ich weiß, unterstützt das normale
sftp
Befehlszeilenprogramm das Lesen und Speichern einer Pipe als Remote-Datei nicht. Es gibt jedoch SSH / SFTP-Bibliotheken für die meisten modernen Programmiersprachen (Perl, Python, Ruby, C #, Java, C usw.). Wenn Sie wissen, wie man eine dieser Sprachen verwendet, sollte es einfach sein, ein Dienstprogramm zu schreiben, das genau das tut, was Sie benötigen.Wenn Sie mit Shell-Skripten nicht weiterkommen, können Sie das SCP-Protokoll so oft fälschen, dass eine Datei übertragen wird. Hier ist ein Beispiel:
Dies erzeugt
some-file
in/some/directory
mit Berechtigungen auf dem Remote - System 644. Der Inhalt der Datei wird , was auch immer$cmd
auf die Standardausgabe schreibt. Beachten Sie, dass Sie den Befehl zweimal ausführen, unabhängig vom Ressourcenverbrauch und den damit verbundenen Nebenwirkungen. Und der Befehl muss jedes Mal dieselbe Anzahl von Bytes ausgeben.quelle
Wenn Sie Perl schreiben können, können Sie versuchen, Net :: SFTP :: Foreign zu verwenden, das Dateien von einem geöffneten Dateideskriptor über SFTP übertragen kann:
quelle