tar: додайте всі файли та каталоги до поточного каталогу, Включаючи .svn тощо


90

Я намагаюся 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)


5
Може це питання належить суперкористувачеві?
Peter Jaric,

Відповіді:


76

Не створюйте файл 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.

1
Хороша відповідь, але у мене ситуація, коли я змушений запускати цю команду всередині каталогу, який повинен бути упакований. У мене недостатньо дозволів для запуску на вулицю.
Гексод,

Ідеальне місце для упаковки - це / tmp точно.
Andre Fellows

46

Якщо ви дійсно не хочете включати верхній каталог у tarball (і це, як правило, погана ідея):

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

Мені потрібно виключити верхній каталог, і мені потрібно помістити tar у базовий каталог.
Micha

@Micha робить скрипт bash для архівування та копіювання файлу після
Федір РИХТІК

2
Вам здається - у -czf, я думаю.
UpTheCreek

10
man tar: першим аргументом tar повинен бути функція; або одну з букв Acdrtux, або одну з довгих назв функцій. Буква функції не повинна мати префікс- і може поєднуватися з іншими опціями з однієї літери.
rkhayrov

4
Досі не працює, я все ще маю "." як головний каталог у моєму tarball
A. Gille

43

Існує кілька кроків:

  1. Замініть *, .щоб включити також приховані файли.
  2. Для створення архіву в тому ж каталозі a --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 .

7
Я прочитав усі відповіді та коментарі, і це найкращий спосіб створити tarball в тому ж режимі. З цієї відповіді я також зрозумів, чому трапляється ця помилка.
Шимон Садло,

Якщо ви хочете , щоб побачити прогрес , в той час як це стиснення файлу дьоготь, ви можете додати додатковий прапор --verbose, наприклад , так: -czvf.
Мастріанні

18

в каталозі, який потрібно стиснути (поточний каталог) спробуйте наступне:

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

2
Але зараз він скаржиться, що файл "." змінився під час читання. Чи можу я бути впевненим, що всі файли були включені?
Jaan

1
Це виключає всі .gzфайли в каталозі.
omerfarukdogan

12

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

cd ..
tar czf workspace.tar.gz workspace

Якщо припустити, що каталог, який ви хотіли gzip, називали робочою областю.


І це дозволяє уникнути проблеми зі зміною файлу.
Джонатан Леффлер,

Не працює, коли користувач не має дозволу на запис у батьківській папці.
Йоахім Вагнер,

Саме @JoachimWagner!
p01ymath

1
@JoachimWagner. Якщо у вас немає дозволу на запис, змініть його на:tar -czf /path/to/where/you/do/have/permission/workspace.tar.gz workspace
bramp

1
Мені довелося вивезти -до, czfщоб змусити це запрацювати. В іншому випадку я отримував Cannot stat: No such file or directoryповідомлення про помилку.
Phemelo Khetho

6

Ви можете виправити .форму, використовуючи --exclude:

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

5

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

tar -czf workspace.tar.gz .

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

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update

Потім файл буде оброблений, і він повинен знаходитись у робочій області - він трохи потворний, але просто необхідний (все це лише обхідний шлях ...)
Майка,

Добре, я додам це виправлення :)
Пітер Ярік,

І якщо вам потрібно мати можливість запускати це неодноразово, додайте 'rm workspace.tar.gz' перед рядком tar.
Peter Jaric,

Якщо ви хочете застосувати цілий диск до цього самого диска, здається, у вас немає багато варіантів.
BeeOnRope

4

Насправді проблема полягає в варіантах стиснення. Хитрість полягає в тому, що труба, яка отримує смолу, надходить до компресора, замість використання вбудованих опцій. До речі, це також може забезпечити вам краще стиснення, оскільки ви можете встановити додаткові параметри стиснення.

Мінімальний вміст смоли:

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

Труба до компресора на ваш вибір. Цей приклад є багатослівним і використовує xz з максимальним стисненням:

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

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


Дякую! Врятоване життя
Стівен

2

Проблема більшості запропонованих тут рішень полягає в тому, що смола міститься ./на початку кожного запису. Отже, це призводить до того, що .каталог відкривається через компресор графічного інтерфейсу. Отже, що я в підсумку зробив:

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). Отже, це рішення не спрацює, якщо ви намагаєтеся створити пакет, який містить безліч записів (каталогів та файлів) в каталозі, який ви намагаєтесь створити.


1

Гарне запитання. У ZSH ви можете використовувати модифікатор globbing (D), який розшифровується як "dotfiles". Порівняйте:

ls $HOME/*

і

ls $HOME/*(D)

Це правильно виключає спеціальні записи каталогу .та ... У Bash ви можете .*явно включити файли крапок:

ls $HOME/* $HOME/.*

Але це включає, .а ..також, так що це не те, що ви шукали. Я впевнений, що є якийсь спосіб створити *файли відповідних точок у bash.


У bash використовуйте .??*для зіставлення всіх файлів крапок not .та ... Це не отримує одноточкові файли крапок (наприклад .a). Щоб отримати їх теж, використовуйте більш складні .[^.]*.
Скотт Мінстер,

1

Ще одне рішення, якщо припустити, що кількість елементів у папці не є величезною:

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

( ls -Aдрукує звичайні та приховані файли, але не "." та "..", як ls -aце робить.)


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

Зазначення .??*включатиме "крапкові" файли та каталоги, які мають щонайменше 2 символи після крапки. Зворотний бік - це не буде включати файли / каталоги з одним символом після крапки, наприклад .a, якщо такі є.


0

Якщо простір на дисковому просторі не є проблемою, це також може бути дуже просто зробити:

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

0

Я сам мав подібну ситуацію. Я думаю, що найкраще створити tar в іншому місці, а потім використовувати -C, щоб повідомити tar базовій директорії для стиснених файлів. Приклад:

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

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


0

Через 10 років у вас є альтернатива tar, проілюстрована Git 2.30 (Q1 2021), яка використовує " git archive" ( людина ) для створення тарболу звільнення замість tar.
(Вам не потрібен Git 2.30, щоб застосувати цю альтернативу)

Див. Коміт 4813277 (11 жовтня 2020 р.) Та коміт 93e7031 (10 жовтня 2020 р.) Рене Шарф ( rscharfe) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 63e5273 , 27 жовтня 2020)

Makefile: використовуйте git init / add / commit / archive для dist-doc

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

Зменшіть залежність від зовнішніх інструментів, створивши архіви розподілу для документації HTML та сторінок, використовуючи команди ( man ) замість tar. Це надає записам архіву ті самі метадані, що й у дистрибутивному архіві для двійкових файлів.git

Отже, замість:

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

Спочатку це було запропоновано, оскільки, як пояснено тут , на якійсь екзотичній платформі може бути старий розподіл смол з відсутніми параметрами.


-1

Використання 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

-J - в посібнику --xz; у поєднанні з -c - це лише початок того, що комп'ютер назве "веселим" :)
Ricalsin

Ха-ха, мій міні-сервер вдома більше обмежений дисковим простором, ніж процесором :) Хоча хороший момент; Я зміню його на використання gzip.
Ендрю Ганнерсон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.