Linux の zip と Bash スクリプトでのディレクトリの除外

Linux の zip と Bash スクリプトでのディレクトリの除外

特定のフォルダーを zip 圧縮し、そのフォルダー内の特定のサブディレクトリを無視する bash/shell スクリプトを作成しようとしています。

これは私が圧縮しようとしているフォルダです」同期テスト5「:」

ここに画像の説明を入力してください

私のbashスクリプトは無視リストを生成します(に基づく) で、次のように zip 関数を呼び出します。

#!/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"

このスクリプトはエラーなしで実行できますが、ない指定したディレクトリを無視/除外します。

そこで、シェル スクリプトに実行しようとしたコマンドを出力させました。そのコマンドは次のようになります。

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

上記のコマンドを次のように putty で直接実行すると、動作します。

ここに画像の説明を入力してください

では、なぜ私のシェル スクリプトは意図したとおりに動作しないのでしょうか? 実行されるコマンドは同一です (シェルと Putty で直接)。

答え1

除外リストで何を達成しようとしているのかわかりません"**\*"が、私が読んだところによると、-x はパターンに一致する名前のファイルを除外し、それらのファイルが存在するディレクトリは考慮しません。

ディレクトリを除外する最も簡単な方法は、一時的にそれらの実行権限を削除することです。例:

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

何らかの理由でスクリプトを中止する場合は、必ず実行権限を復元してください。

答え2

この回答によると、https://superuser.com/a/496903/356580次のようなものが必要です:

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

アスタリスクを使ってエスケープすることもできます。コマンドラインで置換するとエスケープされます。例:

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

しかし、それぞれに好みがあります。必要なのは、置換によって実行されるコマンドが以下のいずれかになることです。

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/*"

この方法では、アスタリスク文字が zip に送信され、コマンド ラインでファイルがグロブ化されることはありません。

関連情報