У меня есть куча tar
файлов в каталоге, и я хочу извлечь из них все файлы сразу. Но это, похоже, ничего не делает:
$ tar xf *.tar
Что тут происходит? Как распаковать сразу кучу файлов?
У меня есть куча tar
файлов в каталоге, и я хочу извлечь из них все файлы сразу. Но это, похоже, ничего не делает:
$ tar xf *.tar
Что тут происходит? Как распаковать сразу кучу файлов?
Первоначально команда tar
предназначалась для использования с устройствами с магнитной лентой. Поскольку имело смысл выполнять tar
только на одном устройстве за раз, синтаксис был разработан для предположения об одном и только одном устройстве. Предполагалось, что первым переданным файлом или каталогом будет устройство, на котором хранится рассматриваемый архив, а также любые другие файлы или каталоги, в которых содержимое архива должно быть включено в операцию. Таким образом, для извлечения tar
(опция x
) первый переданный файл будет архивом, а все остальные файлы будут файлами для извлечения. Итак, если есть два файла *.tar
(скажем, a.tar
и b.tar
), ваша команда расширится до:
$ tar xf a.tar b.tar
Если a.tar
не содержит файл с именем b.tar
, команда tar
ничего не делает и тихо завершает работу. Досадно, что версия tar
для Solaris не сообщает о каких-либо проблемах ни в коде возврата, ни в подробном параметре (v
). Между тем, GNU tar
возвращает 2
и рассылает спам STDERR
даже при отключенной опции verbose:
tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors
Слишком поздно переписывать tar
, чтобы принимать несколько архивных файлов в качестве входных данных, но обойти это ограничение несложно.
Для большинства людей запуск tar
несколько раз для нескольких архивов является наиболее целесообразным вариантом. Передача всего одного имени файла в tar xf
приведет к извлечению всех заархивированных файлов, как и следовало ожидать. Один из подходов заключается в использовании цикла оболочки for
:
$ for f in *.tar; do tar xf "$f"; done
Другой способ — использовать xargs
:
$ ls *.tar | xargs -i tar xf {}
Кроме того, вы можете использовать одну из нескольких альтернативных tar
программ чтения файлов. . Наконец, по-настоящему увлеченный программист может легко написать замену tar
, которая будет работать именно так, как нужно. формат прост, и многие языки программирования имеют библиотеки для чтения tar
файлов. . Например, если вы программист Perl, взгляните на модуль Archive::Tar
.
Слепое распаковывание кучи файлов может привести к непредвиденным проблемам. Наиболее очевидным является то, что конкретное имя файла может быть включено более чем в один файл tar
. Поскольку tar
по умолчанию перезаписывает файлы, точная версия файла, который у вас получится, будет зависеть от порядка обработки архивов. Что еще более тревожно, вы можете получить поврежденную копию файла, если попробуете эту «умную» оптимизацию:
for f in *.tar; do
tar xf "$f" &
done
wait
Если и a.tar
, и b.tar
содержат один и тот же файл и попытаются извлечь его одновременно, результаты будут непредсказуемыми.
Связанная с этим проблема, особенно при получении архивов из ненадежного источника, связана с возможностью tarbomb.
Одним из частичных решений было бы автоматическое создание нового каталога для извлечения в:
for f in *.tar; do
d=`basename "$f" .tar`
mkdir "$d"
(cd "$d" && tar xf "../$f")
done
Это не поможет, если файл в архиве указан с абсолютным путем (что обычно является признаком злого умысла). Добавление такой проверки оставлено читателю в качестве упражнения.
for f in *.tar; do tar xf "$f"; done
- person Enoon; 09.03.2016
Если все файлы tar находятся в одной папке, то я делаю это в оболочке tcsh. Работает все время.
find -iname \*.tar -exec tar -xvf {} \;
Это то же самое, что и приведенный выше ответ, я думаю, немного более лаконичный.