tar: добавить все файлы и каталоги в текущий каталог, включая .svn и т. д. - PullRequest
71 голосов
/ 06 сентября 2010

Я пытаюсь tar.gz каталог и использовать

tar -czf workspace.tar.gz *

Полученный tar включает в себя каталоги .svn в подкаталогах, но НЕ в текущем каталоге (так как * раскрывается только в «видимые» файлы перед передачей в tar

Я пытался

tar -czf workspace.tar.gz . вместо этого, но тогда я получаю ошибку, потому что '.' изменилось при чтении:

tar: ./workspace.tar.gz: file changed as we read it

Есть ли хитрость, чтобы * соответствовал всем файлам (включая префикс с точкой) в каталоге?

(с использованием bash в Linux SLES-11 (2.6.27.19)

Ответы [ 15 ]

57 голосов
/ 06 сентября 2010

Не создавайте файл tar в каталоге, который вы упаковываете:

tar -czf /tmp/workspace.tar.gz .

делает трюк, за исключением того, что при распаковке он извлекает файлы по всему текущему каталогу. Лучше сделать:

cd ..
tar -czf workspace.tar.gz workspace

или, если вы не знаете название каталога, в котором вы были:

base=$(basename $PWD)
cd ..
tar -czf $base.tar.gz $base

(Это предполагает, что вы не переходили по символическим ссылкам, чтобы добраться до того места, где вы находитесь, и что оболочка не пытается угадать вас, перепрыгивая через символическую ссылку - bash не заслуживает доверия в этом отношении. Если вы надо беспокоиться об этом, используйте cd -P .., чтобы сделать каталог физических изменений. Глупо, что это не поведение по умолчанию, на мой взгляд - сбивающее с толку, по крайней мере, для тех, для кого cd .. никогда не имел никакого альтернативного значения.)


Один комментарий в дискуссии гласит:

Мне нужно [...] исключить верхний каталог, а мне нужно [...] поместить tar в базовый каталог.

Первая часть комментария не имеет особого смысла - если файл tar содержит текущий каталог, он не будет создан при извлечении файла из этого архива, поскольку по определению текущий каталог уже существует (за исключением очень странные обстоятельства).

Вторая часть комментария может рассматриваться одним из двух способов:

  1. Либо: создайте файл где-нибудь еще - /tmp - это одно из возможных мест - и затем переместите его обратно в исходное местоположение после его завершения.
  2. Или: если вы используете GNU Tar, используйте опцию --exclude=workspace.tar.gz. Строка после = является шаблоном - пример - самый простой шаблон - точное совпадение. Возможно, вам придется указать --exclude=./workspace.tar.gz, если вы работаете в текущем каталоге вопреки рекомендациям; вам может потребоваться указать --exclude=workspace/workspace.tar.gz, если вы работаете на один уровень выше, чем предложено. Если вы хотите исключить несколько файлов tar, используйте '*', как в --exclude=./*.gz.
42 голосов
/ 06 сентября 2010

Если вы действительно не хотите включать топ-каталог в архив (и это вообще плохая идея):

tar czf workspace.tar.gz -C /path/to/workspace .
27 голосов
/ 19 сентября 2016

Необходимо выполнить несколько шагов:

  1. Заменить * на ., чтобы включить скрытые файлы.
  2. Чтобы создать архив в том же каталоге--exclude=workspace.tar.gz может использоваться для исключения самого архива.
  3. Чтобы предотвратить ошибку tar: .: file changed as we read it, когда архив еще не создан, убедитесь, что он существует (например, с использованием touch), поэтому - исключить совпадений с именем файла архива.(Это не совпадает с тем, что файл не существует)

В сочетании это приводит к следующему сценарию:

touch workspace.tar.gz
tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
17 голосов
/ 02 октября 2014

в каталоге хотите сжать (текущий каталог) попробуйте это:

tar -czf workspace.tar.gz . --exclude=./*.gz
7 голосов
/ 06 сентября 2010

Вы можете включить скрытые каталоги, вернувшись назад в каталог и выполнив:

cd ..
tar -czf workspace.tar.gz workspace

Предполагая, что каталог, который вы хотите скопировать, называется рабочим пространством.

6 голосов
/ 06 сентября 2010

Вы можете исправить форму ., используя --exclude:

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
4 голосов
/ 24 августа 2014

На самом деле проблема с вариантами сжатия. Хитрость заключается в том, что труба дается в компрессор вместо использования встроенных опций. Кстати, это также может дать вам лучшее сжатие, поскольку вы можете установить дополнительные параметры сжатия.

Минимальная смола:

tar --exclude=*.tar* -cf workspace.tar .

Труба к компрессору по вашему выбору. Этот пример многословен и использует xz с максимальным сжатием:

tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz

Решение было протестировано на Ubuntu 14.04 и Cygwin на Windows 7. Это ответ сообщества вики, так что не стесняйтесь редактировать, если обнаружите ошибку.

4 голосов
/ 06 сентября 2010

Обновление: Я добавил исправление для комментария ОП.

tar -czf workspace.tar.gz .

действительно изменит текущий каталог, но почему бы не разместить файл где-нибудь еще?

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update
1 голос
/ 24 мая 2017

Еще одно решение, предполагая, что количество элементов в папке невелико:

tar -czf workspace.tar.gz `ls -A`

(ls -A печатает обычные и скрытые файлы, но не "." И ".." как ls -a делает.)

1 голос
/ 06 сентября 2010

Хороший вопрос.В ZSH вы можете использовать модификатор globbing (D), который обозначает «точечные файлы».Сравните:

ls $HOME/*

и

ls $HOME/*(D)

Это правильно исключает специальные записи каталога . и ...В Bash вы можете использовать .* для явного включения файлов точек:

ls $HOME/* $HOME/.*

Но это также включает в себя . и .., так что это не то, что вы искали.Я уверен, что есть какой-то способ заставить * совпадать с точечными файлами в bash.

...