Hallo,
ich bin da leider ziemlicher Anfänger, kann eher Scripe ändern als
eigene schreiben :-(
Ich bin bei mir in /home/name/data. in data sind 20 Hauptverzeichnisse
mit vielen Unterverz. die ich alle einzeln unter ihren Namen packen
lassen möchte vom Fileserver. Das ist ein sog. Alix Board, ich greife
darauf per Netz zu.
zB
Anleitungen
Datenbuecher
Source_Code
soll dann als Anleitungen.zip, Datenbuecher.zip usw. im Verzeichnis
vorliegen, so dass ich es später mit mv dann auf eine Backup Platte
verschieben kann. Benutzt werden soll das echte ZIP was auch Windows
versteht.
Könnte mir jemand ganz kurz das Script schreiben? Ohne Luxus, d.h. keine
Variablen, das mache ich schon selbst nachher.
Gruss,
Christian
Schau Dir mal den Befehl "find" an, bzw. dessen manpage.
Interessant für Dich dürften hier diese Optionen sein:
type (um nur directories zu erwischen)
maxdepth (nur im aktuellen dir, nicht in tieferen ebenen)
exec (ausführen des zip-befehls)
Glaube ich habs schon zusammen gefrickelt....
Tut jedendalls das was ich brauche :-) Trotzdem danke!
#!/bin/bash
SRC=/home/cjulius/data
DEST=/home/cjulius/archiv/backup
cd $SRC
#in das Verzeichnis in dem diese Verzeichnisse alle liegen.
for i in $(find . -mindepth 1 -maxdepth 1 -type d)
do
tar -cvzf $DEST/${i}.tgz $i > $DEST/backup.log
done
Habe tar benutzt, da zip unter Linux keine Attribute sichert. Und WinRar
kann tgz auch zurück lesen.
Nur leider sind die Umlaute zerschossen, die die Verzeichnisse teilweise
haben.
Vorsicht wenn in dem Quellverzeichnis nicht nur Unterverzeichnisse,
sondern auch normale Dateien sind die nicht gepackt werden sollen.
Vorsicht wenn die Verzeichnisnamen auch Leerzeichen enthalten.
Damit beides ohne find funktioniert, sind extra Befehle nötig.
Gerd E. schrieb:> Vorsicht wenn in dem Quellverzeichnis nicht nur Unterverzeichnisse,> sondern auch normale Dateien sind die nicht gepackt werden sollen.>> Vorsicht wenn die Verzeichnisnamen auch Leerzeichen enthalten.>> Damit beides ohne find funktioniert, sind extra Befehle nötig.
Das hilft nix gegen Leerzeichen und andere Sonderzeichen. Das for wird
die weiterhin als Trennzeichen interpretieren und dann kommt beim Zip
Müll an.
Dazu musst Du $IFS anpassen, siehe z.B.
https://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html
oder eben find verwenden, das hat da keine Probleme mit.
Gerd E. schrieb:> Lukey S. schrieb:>>> for n in */; do zip -r "$n" "$n"; done>>> Das hilft nix gegen Leerzeichen und andere Sonderzeichen. Das for wird> die weiterhin als Trennzeichen interpretieren und dann kommt beim Zip> Müll an.>> Dazu musst Du $IFS anpassen, siehe z.B.> https://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html
Man sollte sowas immer erst selbst nachprüfen, ich kann damit keine
Probleme feststellen:
>> Das hilft nix gegen Leerzeichen und andere Sonderzeichen. Das for wird> die weiterhin als Trennzeichen interpretieren und dann kommt beim Zip> Müll an.
Man konnte an dem "_" im Verzeichnisnamen schon sehen, daß der OP keiner
von den Deppen ist, die Sonder- oder Leerzeichen in Dateinamen benutzen.
;-)
1
ls | while read i; do zip -r "${i}.zip" "${i}"; done
oder, wenn auch Dateien im Verzeichnis liegen, aber nur die
Unterverzeichnisse gezippt werden sollen:
1
find . -mindepth 1 -maxdepth 1 -type d -exec zip -r "{}.zip" {} \;
Ich finde ohnehin: "| while read" wird prinzipiell unterbewertet.
Daniel A. schrieb:> Man sollte sowas immer erst selbst nachprüfen, ich kann damit keine> Probleme feststellen:
hängt dann vermutlich von der verwendeten Shell und deren Version ab.
Ich hatte mit sowas schon genug Ärger und verwende daher seit Jahren
immer find oder $IFS. Aber ist tatsächlich schon länger her daß ich es
das letzte mal ausprobiert habe.
Gerd E. schrieb:> Daniel A. schrieb:>> Man sollte sowas immer erst selbst nachprüfen, ich kann damit keine>> Probleme feststellen:>> hängt dann vermutlich von der verwendeten Shell und deren Version ab.
Jede mir bekannte unixoide Shell macht das Word-Splitting vor der
Filename-Expansion. Wäre es andersherum, würden in einem Verzeichnis,
das nur die Datei "a b" enthält, der Befehl
1
ls *
nicht, wie erwartet, diesen Dateinamen, sondern stattdessen die
Fehlermeldungen
1
ls: cannot access 'a': No such file or directory
2
ls: cannot access 'b': No such file or directory
ausgeben. Hast du so etwas schon einmal erlebt?
Beim Shell-Befehl for ist es nicht anders.
$> mkdir a b "a b c"
$> ls -la
total 20
drwxrwxr-x 5 rayman rayman 4096 Jan 11 08:32 ./
drwxr-xr-x 6 rayman rayman 4096 Jan 11 08:32 ../
drwxrwxr-x 2 rayman rayman 4096 Jan 11 08:32 a/
drwxrwxr-x 2 rayman rayman 4096 Jan 11 08:32 a b c/
drwxrwxr-x 2 rayman rayman 4096 Jan 11 08:32 b/
$> for i in ?*; do tar cvzf "${i}".tgz "${i}"; done
$> ls -la
total 32
drwxrwxr-x 5 rayman rayman 4096 Jan 11 08:33 ./
drwxr-xr-x 6 rayman rayman 4096 Jan 11 08:32 ../
drwxrwxr-x 2 rayman rayman 4096 Jan 11 08:32 a/
drwxrwxr-x 2 rayman rayman 4096 Jan 11 08:32 a b c/
-rw-rw-r-- 1 rayman rayman 113 Jan 11 08:33 a b c.tgz
-rw-rw-r-- 1 rayman rayman 110 Jan 11 08:33 a.tgz
drwxrwxr-x 2 rayman rayman 4096 Jan 11 08:32 b/
-rw-rw-r-- 1 rayman rayman 109 Jan 11 08:33 b.tgz
Die sauberste Lösung mit find und tar hast du selber schon gefunden. Die
kannst das Kommando noch ein wenig zusammenpacken:
find $SRC -mindepth 1 -maxdepth 1 -type d -exec tar cvzf $DEST/{}.tgz {}
\; > $DEST/backup.log 2>&1
das zusammenpacken spart dir eine Fehlerprüfung beim cd (wenn der nicht
funktioniert wird sonstwas zusammengepackt)
und das 2>&1 sorgt dafür, dass auch Fehlermeldungen im Log landen.
Hallo,
also bei mir mit tar läuft das ganz gut, dauert leider nur ewig, daher
werde ich es wohl als cronjob nachts laufen lassen. Gibt es eine
Möglichkeit dass das komprimierte Archiv nur ge-updated wird? Es ist ein
ext4 Laufwerk, was ich per samba auch unter Windows benutze.
Benutze ich -d in der Tar Command Line bekomme ich
tar: Von den Optionen „-Acdtrux“, „--delete“ oder „--test-label“ ist
jeweils nur eine erlaubt
„tar --help“ oder „tar --usage“ gibt weitere Informationen.
oder
tar: Kann komprimierte Archive nicht aktualisieren
„tar --help“ oder „tar --usage“ gibt weitere Informationen.
Ich ziehe Befehle übrigens gern auseinander da ich diese geschachtelten
Ausdrücke nachher kaum nachvollziehen kann.
PS:
Beobachte das Packen grad: Interessant ist, dass Linux sich gleichzeitig
3 Archive vornimmt obwohl es eine sequentielle Anweisung ist, die
Bytezahlen steigen bei den drei Dateien, die grad erzeugt werden
synchron.
Sachen gibts..... :-)
Gruss,
Christian
Gerd E. schrieb:> hängt dann vermutlich von der verwendeten Shell und deren Version ab.
Sorry, das halte ich für ein Gerücht. Ich arbeite seit 1984 mit Unix und
deren Derivaten. Die verhielten sich alle gleich bzgl.
Dateinamensauflösung.
> Ich hatte mit sowas schon genug Ärger und verwende daher seit Jahren> immer find oder $IFS. Aber ist tatsächlich schon länger her daß ich es> das letzte mal ausprobiert habe.
Du hast einfach nicht beachtet, dass die Gänsefüßchen in
for n in */; do zip -r "$n" "$n"; done
genau die Tatsache berücksichtigen, dass die Pade, die zu "$n" aufgelöst
werden, Leerzeichen enthalten können.
Es kommt also nicht auf die Version der Shell an, sondern auf die Art
und Weise der Nutzung.
Mit
for n in */; do zip -r $n $n; done
ohne Gänse bist Du natürlich verratzt und verkauft.
Christian J. schrieb:> also bei mir mit tar läuft das ganz gut, dauert leider nur ewig, daher> werde ich es wohl als cronjob nachts laufen lassen. Gibt es eine> Möglichkeit dass das komprimierte Archiv nur ge-updated wird?
Nein, dazu müßtest Du das komprimierte Archiv vorher dekomprimieren. Das
Teure an gepackten Tar-Archiven ist meistens auch nicht das Archivieren
der Dateien, sondern das Komprimieren. Dabei gibt es Hilfe in Form des
Programms "pigz", das genau wie gzip funktioniert, nur parallel:
1
tar c source/ | pigz -p 4 > target.tgz
komprimiert und
1
pigz -cdp 4 target.tar.gz | tar x
dekomprimiert mit jeweils 4 (-p) Threads.
Was allerdings geht, ist das Tar-Archiv erst zu dekomprimieren, dann zu
aktualisieren, und es dann wieder zu komprimieren. Dabei kannst Du ganz
verschiedene Komprimierer für Deine tar-Archive benutzen, neben Gnuzip
etwa auch bzip2 oder xz. Die komprimieren zwar beide langsamer als gzip,
dafür aber auch wesentlich besser (alle Daten ermittelt mit einem 29 MB
großen Javadoc-Verzeichnis für eine Software mit ca. 100kLOC):
1
xz -c
2
=====
3
Compress (xz -c html.tar > html.tar.xz) : 6.42 s
4
Decompress (unxz html.tar.xz) : 0.15 s
5
Filesize (html.tar.xz) : 806.5 KB
6
7
bzip2 -c
8
========
9
Compress (bzip2 -c html.tar > html.tar.bz2) : 4.86 s
10
Decompress (bunzip2 html.tar.bz2) : 0.57 s
11
Filesize (html.tar.bz2) : 868.42 KB
12
13
gzip -c
14
=======
15
Compress (gzip -c html.tar > html.tar.gz) : 0.49 s
16
Decompress (gunzip html.tar.gz) : 0.45 s
17
Filesize (html.tar.gz) : 1.68 MB
Die einzigen beiden mir bekannten Programme, die komprimierte Archive
aktualisieren können, sind solche, die Archivierer und Komprimierer in
einem sind, nämlich 7z und zip. Dabei geht das entweder auf Kosten der
Größe des Archivs, oder auf Kosten der Zeit für die Komprimierung:
1
zip
2
===
3
Compress (zip -r html.zip html/) : 0.59 s
4
Decompress (unzip html.zip) : 0.36 s
5
Filesize (html.zip) : 4.4 MB
6
7
7z
8
==
9
Compress (7z a html.7z html/) : 4.74 s
10
Decompress (7z x html.7z) : 0.37 s
11
Filesize (html.7z) : 868 KB
Für Deine eigenen Daten mußt Du selbst rechnen und ggf. testen. YMMV.
c.m. schrieb:> vorsicht mit zip. AFAIR gibts da ein 2GB limit bei quell- und/oder> ziel
Schon lange nicht mehr, es wird dann intern zip64 benutzt. Damit hat man
dann zumindest unter Linux keine Probleme.
ABER:
Der Windows-interne Unzipper ist da leider nur zu sich selbst
kompatibel, da es sich nicht ganz an den Standard hält (oh welch'
Überraschung bei Windows...). Erkennbar daran, dass im Archiv abstrus
grosse Files mit Petabytes etc. aufgelistet werden. Von Windows selbst
gepackte Files sind natürlich kein Problem... Muss man halt bei
Problemen externe Tools wie 7zip, Winzip etc. benutzen.
Beim Mac ist es ähnlich krank. Mindestens bis 10.11 kann zwar zip grosse
Files einpacken, dem unzip dazu fehlt aber die 64bit-Extension :-O
Ich hoffe mal der Kommentar zu Leerzeichen und Umlauten war ein Scherz.
Die gehen seit Jahren wenn nicht Jahrzehnten ohne Probleme...
Nur sollte man beachten das Windows, weil es Windows ist, natürlich
wieder alles anders macht und kein UTF8 sonder 16 nutzt...
Sheeva P. schrieb:> Nein, dazu müßtest Du das komprimierte Archiv vorher dekomprimieren. Das> Teure an gepackten Tar-Archiven ist meistens auch nicht das Archivieren
Moment, wie kann man denn tar veranlassen nur das einzupacken, was ein
gesetztes Archiv Bit hat? Ich hatte das alles schon mal fertig aber
durhc einen Datencrash war das Skript dann leider weg.
Wenn sich in einem Verzeichnis nichts geändert hat, dann muss tar das ja
auch nicht anfassen.
Anbei mal das Skript was bei mir die inkrementalen Backups mit rsync 1 x
Tag macht, irgendwo mal gefunden und dann mit anderem zusammen
gebastelt, so dass die Sicherungsplatte auch RO ist.
1
#!/bin/bash
2
3
# ------------- System Commands --------------------
# die nächste Zeile kann man erst einmal auskommentieren und das script mit z.B. ./name.sh -d unter normalen Benutzerrechten testen. Wenn dann alles klappt # wieder entfernen und cron oder anacron job einrichten!
33
if((`$ID-u`!=0));then{$ECHO"Sorry, must be root. Exiting...";exit;}fi
34
35
# Check Customization
36
if![-b$MOUNT_DEVICE];then{$ECHO"Error: Mount device $EXCLUDES isn't valid";exit;}fi
igor schrieb:> Ich hoffe mal der Kommentar zu Leerzeichen und Umlauten war ein Scherz.
Nein.
> Die gehen seit Jahren wenn nicht Jahrzehnten ohne Probleme...
Ebenfalls nein. Leer- und Sonderzeichen in Dateinamen erzeugen immer
wieder Probleme bei der Interoperabilität zwischen verschiedenen
Anwendungen und Systemen. Vernünftige und kompetente Menschen verzichten
daher auf sowas.
Christian J. schrieb:> Moment, wie kann man denn tar veranlassen nur das einzupacken, was ein> gesetztes Archiv Bit hat? Ich hatte das alles schon mal fertig aber> durhc einen Datencrash war das Skript dann leider weg.
Keine Ahnung, das "Archiv-Bit" ist IIRC eine reine Windows-Geschichte
und wird von UNIX und Linux nicht unterstützt.
> Wenn sich in einem Verzeichnis nichts geändert hat, dann muss tar das ja> auch nicht anfassen.
Um herauszufinden, ob eine Datei geändert worden ist, orientieren sich
UNIX und Linux in der Regel an deren Datumsstempeln.
PS:
Ich habe noch dieses dicke Buch hier, seit gut 2 Jahren. Ich werde mich
jedoch mangels Notwendigkeit im privaten Umfeld nie damit befassen. Wenn
es einer haben will, für 25 Euro geht es weg, hat damals 39 gekostet.
Nagelneu und unbenutzt.
Christian J. schrieb:> PS:>> Ich habe noch dieses dicke Buch hier, seit gut 2 Jahren. Ich werde mich> jedoch mangels Notwendigkeit im privaten Umfeld nie damit befassen. Wenn> es einer haben will, für 25 Euro geht es weg, hat damals 39 gekostet.> Nagelneu und unbenutzt.
Nana, wenn es denn unbedingt so eine teure, gebundene Übersetzung sein
muss...
Für mich ist das da die Referenz: Advanced bash-scripting Guide
* <http://www.tldp.org/guides.html>
Nur mal so ne Frage, da ich langsam in die Materie rein komme diese
Scripts zu schreiben. Mühsam, mühsam.....
Ich habe 3 Cron Jobs, die mir stündliche, tägliche und ein wöchentliches
Backup erzeugen mittels des Raspberrys, der im Netz mit drin hängt. Der
Kerl ist nicht der schnellste, also muss ich verhindern, dass sich cron
Jobs schachteln und die Kiste letztlich abstürzt.
Die cron Jobs werden aufgerufen mit
zip_archive daily
zip_archive weekly
zip_archive hourly
Ist da so ok? Ich meine für den Anfang? Dass man sich da totoptimieren
kann um völlig unverständliche Ausdrücke zu erzeugen ist mir klar. Es
muss auch nicht jeder Fehler abgefangen werden, da die Struktur ja fix
ist wo das Ding arbeitet. zip ändert nur bestehende Zip Archive ab, die
sich seitdem letzten Backup verändert haben.
Christian J. schrieb:> Der Kerl ist nicht der schnellste, also muss ich verhindern,> dass sich cron Jobs schachteln und die Kiste letztlich abstürzt.
Der klassische Unix-Weg ist, ein Lock- oder PID-File anzulegen. Ein neu
gestarteter Cronjob prüft erst, ob diese Datei existiert (möglicherweise
auch, ob der entsprechende Prozess tatsächlich läuft) und falls ja,
loggt er das und endet sofort. Bis auf den Logeintrag im Fehlerfall tut
dein Script das auch.
Systemd bietet so ein Verhalten sicherlich auch an, einen Cron enthält
es ja.
@S.R. Svenska
Hallo,
das ist leider das problem meines Scriptes, dass die Lock Files bei
einem Absturz nicht mehr gelöscht werden und natürlich nicht an die PID
des Prozessor gebunden sind. Ich erzeuge ja nur leere Files und prüfe
sie einfach ab. Der Raspberry Pi stürzt einfach ab, wenn zb die
Verzeichnisse zu gross sind. 10GB kann der nicht packen, sobald der
Speicher voll ist schmiert der einfach ab, friert ganz ein.
Hast Du ein einfaches Beispiel dafür wie sowas geht? Wie kann eine Task
zb ihre eigene PID abfragen und weitere Tasks ablocken?
Gruss,
Christian
Du kannst die PID entweder ins Lockfile oder in dessen Dateinamen
schreiben. Da du ja weißt, wie dein Script heißt, kannst du mit "pidof"
dessen PIDs rausbekommen und mit der gespeicherten PID abgleichen (das
Script wird sich immer selbst finden, die eigene PID musst du
ignorieren). Außerdem sollte /proc/$pid/exe auf dein Script zeigen.
Damit kannst du prüfen, ob eine bestimmte Instanz deines Scripts noch
läuft.