it-swarm.com.ru

tar: добавить все файлы и каталоги в текущий каталог, включая .svn и т. д.

Я пытаюсь 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)

66
Micha

Не создавайте файл 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.
52
Jonathan Leffler

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

tar czf workspace.tar.gz -C /path/to/workspace .
42
rkhayrov

Есть несколько шагов:

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

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

touch workspace.tar.gz
tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
19
Veger

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

tar -czf workspace.tar.gz . --exclude=./*.gz
17
empugandring

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

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
6
caf

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

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

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

6
bramp

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

tar -czf workspace.tar.gz .

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

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update
4
Peter Jaric

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

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

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

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

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

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

4
s3v1

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

ls $HOME/*

а также

ls $HOME/*(D)

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

ls $HOME/* $HOME/.*

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

1
loevborg
tar -czf workspace.tar.gz .??* *

Указание .??* будет включать в себя «точечные» файлы и каталоги, которые имеют как минимум 2 символа после точки. Недостатком является то, что он не будет включать файлы/каталоги с одним символом после точки, например, .a, если таковые имеются.

0
Scott Thomson

У меня была похожая ситуация. Я думаю, что лучше создать tar в другом месте, а затем использовать -C, чтобы указать tar базовый каталог для сжатых файлов. Пример:

tar -cjf workspace.tar.gz -C <path_to_workspace> $(ls -A <path_to_workspace>)

Таким образом, нет необходимости исключать ваш собственный tarfile. Как отмечено в других комментариях, -A будет список скрытых файлов.

0
ginin

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

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

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

0
Joachim Wagner

Проблема с большинством решений, представленных здесь, состоит в том, что tar содержит ./ в начале каждой записи. Таким образом, это приводит к наличию каталога . при открытии его через компрессор GUI. Итак, что я в итоге сделал:

ls -1A | xargs -d "\n" tar cfz my.tar.gz

Если у вас уже есть my.tar.gz в текущем каталоге, вы можете использовать это:

ls -1A | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz

Имейте в виду что xargs имеет определенные ограничения (см. xargs --show-limits). Таким образом, это решение не будет работать, если вы пытаетесь создать пакет, который содержит много записей (каталогов и файлов) в каталоге, который вы пытаетесь скопировать.

0
Ellis

Если пространство на диске не является проблемой, это также может быть очень легко сделать: 

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup
0
bicycle