Linux-Zip und Ausschlussverzeichnis im Bash-Skript

Linux-Zip und Ausschlussverzeichnis im Bash-Skript

Ich versuche, ein Bash-/Shell-Skript zu schreiben, um einen bestimmten Ordner zu komprimieren und bestimmte Unterverzeichnisse in diesem Ordner zu ignorieren.

Dies ist der Ordner, den ich versuche zu komprimieren "sync_test5":

Bildbeschreibung hier eingeben

Mein Bash-Skript generiert eine Ignorierliste (bezogen auf) und ruft die Zip-Funktion wie folgt auf:

#!/bin/bash

SYNC_WEB_ROOT_BASE_DIR="/home/www-data/public_html"
SYNC_WEB_ROOT_BACKUP_DIR="sync_test5"
SYNC_WEB_ROOT_IGNORE_DIR="dir_to_ignore dir2_to_ignore"

ignorelist=""
if [ "$SYNC_WEB_ROOT_IGNORE_DIR" != "" ];
then
    for ignoredir in $SYNC_WEB_ROOT_IGNORE_DIR
    do
        ignorelist="$ignorelist $SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/**\*"
    done
fi

FILE="$SYNC_BACKUP_DIR/$DATETIMENOW.website.zip"
cd $SYNC_WEB_ROOT_BASE_DIR;
zip -r $FILE $SYNC_WEB_ROOT_BACKUP_DIR -x $ignorelist >/dev/null
echo "Done"

Nun läuft das Skript fehlerfrei, allerdings ist esnichtIgnorieren/Ausschließen der von mir angegebenen Verzeichnisse.

Ich ließ das Shell-Skript also den Befehl ausgeben, den es ausführen wollte, und zwar:

zip -r 12-08-2014_072810.website.zip sync_test5 -x  sync_test5/dir_to_ignore/**\* sync_test5/dir2_to_ignore/**\*

Wenn ich den obigen Befehl jetzt direkt in Putty ausführe, funktioniert es:

Bildbeschreibung hier eingeben

Warum funktioniert mein Shell-Skript nicht wie vorgesehen? Der ausgeführte Befehl ist identisch (direkt in der Shell und in Putty).

Antwort1

Ich sehe nicht, was Sie mit der Ausschlussliste erreichen möchten "**\*", aber so wie ich es lese, schließt -x Dateien aus, deren Namen einem Muster entsprechen, und berücksichtigt nicht die Verzeichnisse, in denen sie sich befinden.

Die einfachste Möglichkeit, Verzeichnisse auszuschließen, besteht darin, ihnen vorübergehend die Ausführungsberechtigung zu entziehen, z. B.: -

chmod -x ...
zip ...
chmod +x ...

Stellen Sie einfach sicher, dass Sie die Ausführungsberechtigung wiederherstellen, wenn Sie das Skript aus irgendeinem Grund abbrechen.

Antwort2

Dieser Antwort zufolgehttps://superuser.com/a/496903/356580, Sie brauchen so etwas wie:

ignorelist=""
if [ "$SYNC_WEB_ROOT_IGNORE_DIR" != "" ];
then
    for ignoredir in $SYNC_WEB_ROOT_IGNORE_DIR
    do
        ignorelist="$ignorelist \"$SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/*\""
    done
fi

Sie können mit dem Asterix auch einige raffinierte Escape-Zeichen verwenden, so dass es beim Ersetzen in der Befehlszeile maskiert wird, z. B.

ignorelist="$ignorelist $SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/\\*"

Aber jedem das Seine. Sie möchten, dass der Befehl wie folgt aussieht, wenn er durch die Ersetzung ausgeführt wird:

zip -r sync_test.zip sync_test -x sync_test/dir_to_ignore/\* sync_test/dir2_to_ignore/\*
zip -r sync_test.zip sync_test -x "sync_test/dir_to_ignore/*" "sync_test/dir2_to_ignore/*"

Auf diese Weise wird das Asterix-Zeichen an Zip gesendet und es erfolgt kein Datei-Globing in der Befehlszeile.

verwandte Informationen