Forum: PC-Programmierung Linux Frage : Verzeichnisse packen


von Christian J. (Gast)


Lesenswert?

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

von Gerd E. (robberknight)


Lesenswert?

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)

von Joachim S. (oyo)


Lesenswert?

find zu benutzen wäre vermutlich der sinnvollste Weg, aber in diesem 
Fall sollte es auch so gehen:
1
cd /home/name/data; for i in */; do cd "$i"; zip -r "../${i::-1}.zip" *; cd ..; done

von Lukey S. (lukey3332)


Lesenswert?

1
for n in *; do zip -r $n $n; done

von zip (Gast)


Lesenswert?

Christian J. schrieb:
> Ich bin bei mir in /home/name/data. in data sind 20 Hauptverzeichnisse


Also auf einem Linux-OS, evtl. mal
libarchive/FUSE, Archivemount anschauen.

http://www.pcwelt.de/ratgeber/Linux-Praxis-Konsolen-Know-how-8298473.html

Geht auch mit .zip falls ein Win, welches von aussen dann draufguckt 
nichts anderes kennt. Die Archive auch dem Linux-rechner werden wie 
Verzeichnisse bedient.


----

http://www.cybernoia.de/software/archivemount/
http://people.freebsd.org/~kientzle/libarchive/
http://fuse.sourceforge.net

oder halt aus dem repo deiner Distribution

von Christian J. (Gast)


Lesenswert?

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

von Christian J. (Gast)


Lesenswert?

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.

von Christian J. (Gast)


Lesenswert?

Lukey S. schrieb:
> for n in *; do zip -r $n $n; done

So kurz habe ich da ja noch nie gesehen :-) Funzt einwandfrei!

von Gerd E. (robberknight)


Lesenswert?

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.

von LEERZCHN (Gast)


Angehängte Dateien:

Lesenswert?

LEERZCHN machen nur Ärger.

Genau wie Ümläute.


A.S.C.I.I. regelt!

von c.m. (Gast)


Lesenswert?

vorsicht mit zip. AFAIR gibts da ein 2GB limit bei quell- und/oder 
zieldateien.

von Lukey S. (lukey3332)


Lesenswert?

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.
1
for n in */; do zip -r "$n" "$n"; done
...

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?

Lukey S. schrieb:
>
1
> for n in */; do zip -r "$n" "$n"; done
2
>

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.

von Christian J. (Gast)


Lesenswert?

Nein, Leerzeichen sind verpönt und werden durch _ ersetzt aber Umlaute 
doch schon Normalität geworden.

von Daniel A. (daniel-a)


Lesenswert?

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:
1
daniel@colibri:~/projects$ mkdir test
2
daniel@colibri:~/projects$ cd test/
3
daniel@colibri:~/projects/test$ touch $'ab cd\nef'
4
daniel@colibri:~/projects/test$ ls
5
ab cd?ef
6
daniel@colibri:~/projects/test$ for n in *; do zip -r "$n" "$n"; done
7
  adding: ab cd^Jef (stored 0%)
8
daniel@colibri:~/projects/test$ ls
9
ab cd?ef  ab cd?ef.zip
10
daniel@colibri:~/projects/test$ IFS=' '
11
daniel@colibri:~/projects/test$ rm $'ab cd\nef.zip'
12
daniel@colibri:~/projects/test$ for n in *; do zip -r "$n" "$n"; done
13
  adding: ab cd^Jef (stored 0%)
14
daniel@colibri:~/projects/test$ ls
15
ab cd?ef  ab cd?ef.zip
16
daniel@colibri:~/projects/test$ cd ..
17
daniel@colibri:~/projects$ rm -r test

von Sheeva P. (sheevaplug)


Lesenswert?

Gerd E. schrieb:
> Lukey S. schrieb:
>>
1
>> for n in */; do zip -r "$n" "$n"; done
2
>>
>
> 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.

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Ray M. (ray_m)


Lesenswert?

$> 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

von JJ (Gast)


Lesenswert?

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.

von Christian J. (Gast)


Lesenswert?

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.

von Christian J. (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Sheeva P. (sheevaplug)


Lesenswert?

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.

von Georg A. (georga)


Lesenswert?

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

von igor (Gast)


Lesenswert?

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...

von Christian J. (Gast)


Lesenswert?

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.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

So gehts besser :-) Was sich nicht verändert wird auch nicht neu 
eingepackt. tar ist eher etwas für Bandstreamer, da kann nur hinten 
angehängt werden.

von Christian J. (Gast)


Lesenswert?

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 --------------------
4
ID=/usr/bin/id;
5
ECHO=/bin/echo;
6
MOUNT=/bin/mount;
7
RM=/bin/rm;
8
MV=/bin/mv;
9
CP=/bin/cp;
10
TOUCH=/bin/touch;
11
RSYNC=/usr/bin/rsync;
12
DF=/bin/df;
13
TAIL=/usr/bin/tail;
14
SED=/bin/sed;
15
SYNC=/bin/sync;
16
LOGGER=/usr/bin/logger;
17
CHMOD=/bin/chmod;
18
MKDIR=/bin/mkdir;
19
20
# ====================================================================
21
MOUNT_DEVICE=/dev/sdb1;                    # Your Mount device - Ziel
22
MOUNT_RO=true;                             # For write protection set to true
23
SOURCE=/home/cjulius/data
24
SNAPSHOT_RW=/home/cjulius/data_backup;     # where to store the backups - Ziel-Ordner
25
EXCLUDES=/home/cjulius/home_exclude.txt;   # Create the backup_exclude file first!
26
CHECK_HDMINFREE=true;                      # Check free space
27
HDMINFREE=95;                              # Make a backup up to this percentage
28
DAYS=90;                                   # Number of daily backups -1
29
# ======================================================================
30
31
# Make sure we're running as root
32
# 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
37
if ! [ -d $SNAPSHOT_RW ] ; then  $MKDIR -p $SNAPSHOT_RW; fi
38
if ! [ -f $EXCLUDES ] ; then { $ECHO "Error: Exclude File $EXCLUDES missing" ; exit; } fi
39
40
# Check free space on disk
41
GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/';
42
if $CHECK_HDMINFREE ; then
43
        KBISFREE=`$DF /$SNAPSHOT_RW | $TAIL -n1 | $SED -e "$GETPERCENTAGE"`
44
        if [ $KBISFREE -ge $HDMINFREE ] ; then
45
                $ECHO "Error: Not enough space left for rotating backups!"
46
                $LOGGER "Error: Not enough space left for rotating backups!"
47
                exit
48
        fi
49
fi
50
51
# ------------- The Script itself --------------------------------------
52
53
if $MOUNT_RO ; then
54
        # Attempt to remount the RW mount point as RW; else abort
55
        $MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
56
        if (( $? )); then
57
                $ECHO "Error: could not remount $SNAPSHOT_RW readwrite";
58
                exit;
59
        fi;
60
fi;
61
62
63
# *********** Daily Backups ********************************************
64
           # Rotating daily snapshots of /home  
65
66
           # Step 1: Delete the oldest snapshot, if it exists:
67
           # It is NOT moved to the weekly backups level since you can make hundreds of daily backups
68
           if [ -d $SNAPSHOT_RW/daily.$DAYS ] ; then
69
                $RM -rf $SNAPSHOT_RW/daily.$DAYS ;
70
           fi;
71
72
           # Step 2: Shift all other snapshots(s) by one, if they exist (e.g. 6->7...1->2)
73
           OLD=$DAYS;
74
           while [ $OLD -ge 2 ] ; do
75
                OLD=$[$OLD-1]
76
                if [ -d $SNAPSHOT_RW/daily.$OLD ] ; then
77
                        NEW=$[ $OLD + 1 ]
78
                        # Save date
79
                        $TOUCH $SNAPSHOT_RW/.timestamp -r $SNAPSHOT_RW/daily.$OLD
80
                        $MV $SNAPSHOT_RW/daily.$OLD $SNAPSHOT_RW/daily.$NEW
81
                        # Restore date
82
                        $TOUCH $SNAPSHOT_RW/daily.$NEW/.timestamp \
83
                                -r $SNAPSHOT_RW/.timestamp
84
                fi;
85
           done
86
87
           # Step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
88
           # If that exists 0->1
89
           if ! [ -d $SNAPSHOT_RW/daily.0 ] ; then
90
                $MKDIR -p $SNAPSHOT_RW/daily.0
91
                $TOUCH $SNAPSHOT_RW/daily.0/.timestamp
92
           else
93
                $CP -al $SNAPSHOT_RW/daily.0 $SNAPSHOT_RW/daily.1 ;
94
           fi;
95
96
           # Step 4: rsync from the system into the latest snapshot (notice that
97
           # rsync behaves like cp --remove-destination by default, so the destination
98
           # is unlinked first.  If it were not so, this would copy over the other
99
           # snapshot(s) too!
100
           $RSYNC                                                               \
101
                -va --delete --delete-excluded                          \
102
                --exclude-from="$EXCLUDES"                              \
103
                $SOURCE $SNAPSHOT_RW/daily.0 ;
104
105
           # Check return code
106
           # 0 = ok, 
107
           # 24 is also ok. It appears if files were changed or deleted while this script runs
108
           # Other return codes are Error -- see man (1) rsync
109
           if ! [ $? = 24 -o $? = 0 ] ; then
110
                $ECHO "Error: rsync finished on $MOUNT_DEVICE with errors!"
111
                $LOGGER "Error: rsync finished on $MOUNT_DEVICE with errors!"
112
           fi;
113
114
           # Step 5: update the mtime of daily.0 to reflect the snapshot time
115
           $TOUCH $SNAPSHOT_RW/daily.0 ;
116
117
           # Finished!
118
           $ECHO "Finished rsync backup on $MOUNT_DEVICE..."
119
           $LOGGER "Finished rsync backup on $MOUNT_DEVICE..."
120
121
           # For beeing on the secure site...
122
           $SYNC;
123
124
           # And thats it for home.
125
126
127
128
$ECHO "Backup ended"
129
if $MOUNT_RO ; then
130
        # Now remount the RW snapshot mountpoint as readonly
131
        $MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
132
        if (( $? )); then 
133
                $ECHO "Error: Could not remount $SNAPSHOT_RW readonly";
134
                exit;
135
        fi;
136
fi;

von Sheeva P. (sheevaplug)


Lesenswert?

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.

von Sheeva P. (sheevaplug)


Lesenswert?

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.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Kommandozeile vor dem Frühstück für Alle! (Gast)


Lesenswert?

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>;

von Christian J. (Gast)


Lesenswert?

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.
1
#!/bin/bash
2
3
# Erlaubte Parameter sind: daily, hourly, weekly
4
5
DEST_HOME=/home/cjulius/archiv         # Zielverzeichnis Home
6
SRC=/home/cjulius/data                       # Quellverzeichnis
7
8
# Pruefe Eingabe Parameter und erzeuge Zielverzeichnis fuer Backups
9
case "$1" in
10
  weekly|daily|hourly) PARAM='bkp_'$1;;
11
        *) rm $SEMAPHOR;
12
           exit -1;;  # Parameter nicht erkannt
13
esac
14
15
#Zielverzeichnis bilden und Logfile
16
LOGFILE=$DEST_HOME/$PARAM.log
17
DEST=$DEST_HOME/$PARAM
18
SEMAPHOR=$DEST_HOME/$PARAM.run
19
20
# Teste ob schon eine andere Instanz der Scripts läuft
21
if [ -e $SEMAPHOR ];
22
 then
23
   exit -1  # Ja, dann beende Script mit Fehler 1
24
 else 
25
   #Erzeuge leere Semaphor Datei, um Mehrfachaufrude zu vermeiden
26
   touch $SEMAPHOR
27
fi
28
29
# In das Verzeichnis wechseln in dem SRC Verzeichnisse alle liegen.
30
cd $SRC 2>/dev/null ||  { 
31
  echo "Verzeichnis existiert nicht" > $LOGFILE;
32
  rm $SEMAPHOR;
33
        exit -1;
34
}
35
36
# Starte Aufzeichnung im neuen Logfile
37
rm $LOGFILE
38
echo -e $0 'Backup startet um: ' $(date) >> $LOGFILE 
39
40
# ---- Verzeichnisse rekursiv zusammen  packen ------
41
for i in $(find . -mindepth 1 -maxdepth 1 -type d)
42
do
43
    echo -e 'Bearbeite' $i >> $LOGFILE
44
    zip  -1 -ur $DEST/${i}.zip $i >> $LOGFILE 
45
done
46
47
# ---------------------------------------------------
48
echo -e '\nBackup endet um: ' $(date) >> $LOGFILE 
49
50
# Semaphor Datei wieder löschen, um weitere Prozesse frei zu geben
51
rm $SEMAPHOR

von S. R. (svenska)


Lesenswert?

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.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

@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

von S. R. (svenska)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.