Eigentlich geht es hier nicht speziell um Webserver-Backups, sondern eher allgemein um die Verwendung des sftp-Kommandozeilenprogrammes.
In meinem ganz speziellen Fall wollte ich jedoch ein wöchentliches Backup aller PHP-Skripte & Co. von einem Webserver machen, da ich an den PHP-Skripten ständig arbeite und im Hintergrund gerne eine relativ aktuelle funktionierende Kopie haben möchte.
Sucht man im Internet zu Hilfestellungen zum sftp-Kommandozeilenprogramm, endet die Hilfestellung meist mit dem Tipp, doch lieber scp oder rsync zu verwenden.
Dies soll hier nicht der Fall sein, da in meinem Fall der betroffene Webserver jegliche Verbindung außer explizit sftp ausschließt.
Mein Ziel:
Ein kurzes Skript, das fast alle Dateien eines Verzeichnisses auf dem SFTP-Server herunterlädt. Ich paar Dateien und Verzeichnisse möchte ich allerdings vom Herunterladen ausschließen, da sie Bilder, Dokumente und temporäre Daten enthalten, welche ich bei meiner Kopie nicht benötige.
Das schließt die einfachste Verwendung von sftp schonmal aus...
Die einfachste Verwendung...
...wäre nämlich, einfach den gesamten Inhalt des SFTP-Servers oder den gesamten Inhalt eines bestimmten Verzeichnisses herunterzuladen:Alle Daten von wunschordner mit seinen Unterordnern herunterladen:
Nur bestimmte Dateien und Verzeichnisse herunterladen
Voraussetzung:- Wir haben eine Datei liste.txt die den Namen alle Dateien und Ordner enthält, welche heruntergeladen werden sollen. Im Folgenden "die Batch-Datei"
- sshpass ist installiert, um für den Batch-Betrieb das SFTP-Passwort an den SFTP-Server übergeben zu können (wir wollen ja später nicht jedes Mal das Passwort eingeben)
Die Batch-Datei kann wie folgt aussehen:
get -r unterordner1
get -r unterordner2
get -r unterordner3
get .htaccess
get .htuser
get index.php
Das hinten angestellte lokale Downloadverzeichnis /pfad/zu/lokalem/ordner aus dem ersten Beispiel hatte bei mir keine Wirkung mehr – es wurde alles in das aktuelle Verzeichnis reingeladen. Deshalb vorangestellt noch ein cd zum Wunsch-Downloadverzeichnis.
sshpass -p <passwort> sftp -oBatchMode=no -b /pfad/zu/liste.txt user@webserver
Bestimmte Dateien und Verzeichnisse ausschließen
Jetzt wird es komplizierter. Eine --exclude-Funktion, wie es etwa scp anbietet, gibt es hier leider nicht (zumindest hatte ich soetwas nirgends finden können).Was aber, wenn ich alle Dateien eines Verzeichnisses bis auf zwei bestimmte Dateien herunterladen möchte? Noch dazu, wenn in jenem Verzeichnis mal neue Dateien dazu kommen und ich kein festes Datei-Listing für meine Batach-Datei habe?
Meine Lösung war, sich das aktuelle Dateilisting vom SFTP-Server zu holen und daraus eine Batch-Datei zu erstellen.
Meine Batch-Datei, um das Datei-Listing zu erhalten sieht wie folgt aus:
ls -1a
In der Ausgabe, die wir erhalten werden, sind leider auch noch die von sftp ausgeführten Befehle wie sftp> cd wunschordner und die Pfadangaben . und .. enthalten.
Das wollen wir in unserer zu generierenden Batch-Datei nicht haben, deshalb filtere ich dies mit sed raus:
unterordner2
unterordner3
unterordner4
unterordner5
datei1
datei2
datei3
datei4
Nehmen wir an, wir wollen alles, bis auf unterordner3 und datei2 herunterladen.
So nehme ich die beiden Namen zu meiner sed-Regex mit auf.
sed -E '/^\.$|^\.\.$|^sftp|unterordner3|datei2/d'
Nun speichern wir die Ausgabe von sftp direkt in unsere neue Batch-Datei liste.txt
unterordner2
unterordner4
unterordner5
datei1
datei3
datei4
Vor jeden Eintrag muss nun noch ein get -r vorangestellt werden.
Und befinden sich die Dateien nicht im Datei-Root (wir haben bisher ja immer erst in den Ordner wunschordner gewechselt), müssen wir noch ein cd wunschordner in die erste Zeile stellen.
echo "cd wunschordner"|cat - /pfad/zu/tmp.txt > /pfad/zu/liste.txt
rm /pfad/zu/tmp.txt
Nun sollte in der Batch-Datei stehen
get -r unterordner1
get -r unterordner2
get -r unterordner4
get -r unterordner5
get -r datei1
get -r datei3
get -r datei4
Wir haben zwar unschönerweise auch den Dateien ein Rekursiv -r vorangestellt, aber das stört sftp zum Glück nicht.
Und nun alles zusammen – am Ende packe ich noch alles in ein tar-Archiv, das das aktuelle Datum im Dateinamen hat:
# Liste aller gewünschten Dateien/Verzeichnisse erstellen
sshpass -p <passwort> sftp -oBatchMode=no -b /pfad/zu/ls-batch.txt user@webserver | sed -E '/^\.$|^\.\.$|^sftp|unterordner3|datei2/d' | while read line; do echo "get -r $line"; done > /var/tmp/tmp.txt
echo "cd wunschordner"|cat - /var/tmp/tmp.txt > /pfad/zu/batchliste.txt
rm /var/tmp/tmp.txt
# Download und verpacken
mkdir /var/tmp/mybackup
cd /var/tmp/mybackup
sshpass -p <passwort> sftp -oBatchMode=no -b /pfad/zu/batchliste.txt user@ftp
tar -zcvf /pfad/zu/ordner/$(date +"%Y-%m-%d")-backup.tar.gz /var/tmp/mybackup
rm -r /var/tmp/mybackup
![]() ![]() ![]() ![]() |
|
Erstellt am: 08.02.2023 | .Kommentieren |