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)


person Micha    schedule 06.09.2010    source источник
comment
Может, этот вопрос относится к суперпользователю?   -  person Peter Jaric    schedule 06.09.2010


Ответы (16)


Не создавайте 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.
person Jonathan Leffler    schedule 06.09.2010
comment
Хороший ответ, но у меня ситуация, когда я вынужден запускать эту команду внутри каталога, который нужно упаковать. У меня недостаточно прав для запуска его снаружи. - person Hexodus; 09.06.2014
comment
Идеальное место для упаковки - это, безусловно, / tmp. - person Andre Fellows; 07.11.2019

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

  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 .
person Veger    schedule 19.09.2016
comment
Я прочитал все ответы и комментарии, и это лучший способ создать архив в том же каталоге. Из этого ответа я также понял, почему возникает эта ошибка. - person Szymon Sadło; 29.12.2017
comment
Если вы хотите видеть, как идет процесс сжатия вашего tar-файла, вы можете добавить дополнительный флаг для --verbose, например: -czvf. - person Mastrianni; 18.07.2020

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

tar czf workspace.tar.gz -C /path/to/workspace .
person rkhayrov    schedule 06.09.2010
comment
Мне нужно исключить верхний каталог, и мне нужно поместить tar в базовый каталог. - person Micha; 06.09.2010
comment
@Micha создайте сценарий bash для архивации и копирования файла после - person Fedir RYKHTIK; 07.06.2013
comment
Думаю, вам не хватает - в -czf. - person UpTheCreek; 30.10.2014
comment
man tar: первым аргументом tar должна быть функция; либо одна из букв Acdrtux, либо одно из длинных имен функций. Функциональная буква не требует префикса - и может сочетаться с другими однобуквенными параметрами. - person rkhayrov; 30.10.2014
comment
По-прежнему не работает, у меня все еще есть. как верхний каталог в моем архиве - person A. Gille; 21.12.2017

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

tar -czf workspace.tar.gz . --exclude=./*.gz
person empugandring    schedule 02.10.2014
comment
Но теперь он жалуется, что файл. изменен во время чтения. Могу ли я быть уверен, что все файлы включены? - person Jaan; 05.01.2015
comment
Это исключает все .gz файлы в каталоге. - person omerfarukdogan; 05.06.2018

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

cd ..
tar czf workspace.tar.gz workspace

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

person bramp    schedule 06.09.2010
comment
И это также позволяет избежать проблемы с изменением файла. - person Jonathan Leffler; 06.09.2010
comment
Не работает, если у пользователя нет разрешения на запись в родительскую папку. - person Joachim Wagner; 24.05.2017
comment
Именно @JoachimWagner! - person p01ymath; 26.07.2018
comment
@JoachimWagner. Если у вас нет разрешения на запись, измените его на: tar -czf /path/to/where/you/do/have/permission/workspace.tar.gz workspace - person bramp; 16.09.2018
comment
Мне пришлось вынуть - перед czf, чтобы он заработал. В противном случае я получал Cannot stat: No such file or directory сообщение об ошибке. - person Phemelo Khetho; 29.10.2019

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

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
person caf    schedule 06.09.2010

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

tar -czf workspace.tar.gz .

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

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update
person Peter Jaric    schedule 06.09.2010
comment
После этого файл будет обработан и должен находиться в рабочей области - это немного некрасиво, но это просто необходимо (все это просто обходной путь ...) - person Micha; 06.09.2010
comment
Хорошо, я исправлю это :) - person Peter Jaric; 06.09.2010
comment
И если вам нужно иметь возможность запускать это несколько раз, добавьте 'rm workspace.tar.gz' перед строкой tar. - person Peter Jaric; 06.09.2010
comment
Если вы хотите заархивировать весь диск, в тот же самый диск, похоже, у вас не так много вариантов. - person BeeOnRope; 30.07.2017

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

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

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

Подключите к компрессору по вашему выбору. Этот пример подробный и использует xz с максимальным сжатием:

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

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

person Community    schedule 24.08.2014
comment
Спасибо! Спасенная мама жизнь - person Steven; 23.08.2015

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

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). Таким образом, это решение не сработает, если вы пытаетесь создать пакет с большим количеством записей (каталогов и файлов) в каталоге, который вы пытаетесь заархивировать.

person Ellis    schedule 03.03.2016

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

ls $HOME/*

а также

ls $HOME/*(D)

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

ls $HOME/* $HOME/.*

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

person loevborg    schedule 06.09.2010
comment
В bash используйте .??*, чтобы сопоставить все файлы точек, а не . и ... Это не дает файлов с односимвольными точками (например, .a). Чтобы получить и их, используйте более сложный .[^.]*. - person Scott Minster; 10.06.2013

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

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

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

person Joachim Wagner    schedule 24.05.2017

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

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

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

person ginin    schedule 02.04.2018

10 лет спустя у вас есть альтернатива tar, проиллюстрированная Git 2.30 (Q1 2021), в которой используется _ 2_ (человек ) для создания архивного архива выпуска вместо tar.
(Вам не нужен Git 2.30 для применения этой альтернативы)

См. фиксацию 4813277 (11 октября 2020 г.) и commit 93e7031 (10 октября 2020 г.) от Рене Шарфе (rscharfe).
(Объединено Junio ​​C Hamano - - gitster - в commit 63e5273, 27 октября 2020 г.)

Makefile: используйте git init / add / commit / archive для dist-doc

Подписано: Рене Шарфе

Уменьшите зависимость от внешних инструментов, создав архивы распространения для HTML-документации и руководств с помощью git (man) вместо этого дегтя. Это дает записи архива те же метаданные, что и в архиве dist для двоичных файлов.

Так что вместо:

tar cf ../archive.tar .

Вы можете использовать только Git:

git -C workspace init
git -C workspace add .
git -C workspace commit -m workspace
git -C workspace archive --format=tar --prefix=./ HEAD^{tree} > workspace.tar
rm -Rf workspace/.git

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

person VonC    schedule 31.10.2020

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

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

person Scott Thomson    schedule 06.09.2010

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

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup
person bicycle    schedule 01.10.2015

Использование find, вероятно, самый простой способ:

find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+

find . -maxdepth 1 найдет все файлы / каталоги / символические ссылки / и т. Д. В текущем каталоге и выполнит команду, указанную в -exec. {} в команде означает, что список файлов идет сюда, а \+ означает, что команда будет запускаться как:

tar zcvf workspace.tar.gz .file1 .file2 .dir3

вместо того

tar zcvf workspace.tar.gz .file1
tar zcvf workspace.tar.gz .file2
tar zcvf workspace.tar.gz .dir3
person Andrew Gunnerson    schedule 23.05.2013
comment
-J в руководстве - это --xz; в сочетании с -c - это только начало того, что компьютер назовет забавой :) - person Ricalsin; 14.07.2013
comment
Ха-ха, мой домашний мини-сервер больше ограничен дисковым пространством, чем процессором :) Хороший момент; Я заменю его на использование gzip. - person Andrew Gunnerson; 16.07.2013