Распакуйте ZIP-файл и распакуйте содержимое неизвестного имени папки - PullRequest
6 голосов
/ 29 ноября 2010

Мои пользователи будут архивировать файлы, которые будут выглядеть следующим образом:

TEMPLATE1.ZIP
   |--------- UnknownName
                   |------- index.html
                   |------- images
                               |------- image1.jpg

Я хочу извлечь этот файл ZIP следующим образом:

/mysite/user_uploaded_templates/myrandomname/index.html
/mysite/user_uploaded_templates/myrandomname/images/image1.jpg

Моя проблема с UnknownName -Я не знаю, что это такое заранее, и извлечение всего на «базовый» уровень нарушает все относительные пути в index.html

Как я могу извлечь из этого ZIP-файла содержимое из UnknownName?

Есть ли что-нибудь лучше, чем:

1. Extract everything
2. Detect which "new subdidrectory" got created
3. mv newsubdir/* .
4. rmdir newsubdir/

Если на уровне UnknownName более одного подкаталога, я могу отклонить zip-файл этого пользователя.

Ответы [ 3 ]

7 голосов
/ 29 ноября 2010

Я думаю, что ваш подход хорош.Шаг 2 может быть улучшен при извлечении во вновь созданный каталог (позже удаленный), так что «обнаружение» тривиально.

# Bash (minimally tested)
tempdest=$(mktemp -d)
unzip -d "$tempdest" TEMPLATE1.ZIP
dir=("$tempdest"/*)
if (( ${#dir[@]} == 1 )) && [[ -d $dir ]]
    # in Bash, etc., scalar $var is the same as ${var[0]}
    mv "$dir"/* /mysite/user_uploaded_templates/myrandomname
else
    echo "rejected"
fi
rm -rf "$tempdest"
0 голосов
/ 29 ноября 2010

Каждая команда zip и unzip отличается, но обычно есть способ составить список содержимого файла.Оттуда вы можете проанализировать вывод, чтобы определить неизвестное имя каталога.

В Windows, версия Уэльса / Gaily / van der Linden / Rommel 1996 года, это unzip -l.

Конечно, вы можете просто позволить распаковать файлы в любой каталог, в который они захотят, а затем использовать mv, чтобы переименовать каталог в нужный вам каталог.

$tempDir = temp.$$
mv $zipFile temp.$$
cd $tempDir
unzip $zipFile
$unknownDir = *   #Should be the only directory here
mv $unknownDir $whereItShouldBe
cd ..
rm -rf $tempDir

Это всегда хорошая идея для созданиявременный каталог для операций такого типа на случай, если в итоге вы запустите два экземпляра этой команды.

0 голосов
/ 29 ноября 2010

Другой вариант, который я вижу, кроме предложенного вами, - это использовать флаг unzip -j, который будет сбрасывать все пути и помещать все файлы в текущий каталог.Если вы точно знаете, что каждый из ваших TEMPLATE1.ZIP файлов содержит файлы index.html и *.jpg, то вы можете просто сделать что-то вроде:

destdir=/mysite/user_uploaded_templates/myrandomname
unzip -j -d "$destdir"
mkdir "${destdir}/images"
mv "${destdir}/*.jpg" "${destdir}/images"

Это не совсем чистое решение, но, по крайней мере, выне нужно делать разбор, как вы делаете в своем примере.Кажется, я не могу найти ни одной опции, похожей на patch -p#, которая позволила бы вам указать уровень пути.

...