Я пытаюсь написать скрипт bash/shell для архивации определенной папки и игнорирования определенных подкаталогов в этой папке.
Это папка, которую я пытаюсь заархивировать.sync_test5":
Мой скрипт 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, и в командной строке не происходит подстановки имен файлов.