Тар ведущий слэш
tar czf dist.tgz --exclude=".gitignore" .
Это создает файлы в tar с начальным "./", что позже превращается в проблему, когда серверу нужно извлечь части tar.
Может кто-нибудь сказать мне, как упаковать его, чтобы не было ведущих "./"?
6 ответов
Попробуйте --xform
опция, которая использует выражение замены типа sed. Это позволяет вам изменять ссылки на пути, идущие в архив, а не обрабатывать их во время извлечения (например, с помощью --strip-components).
tar --exclude=.gitignore -cz --xform s:'./':: -f dist.tgz ./
Чтобы вывести список файлов по мере их обработки, добавьте -v
а также --show-transformed-name
опции:
tar --exclude=.gitignore -cvz --xform s:'./':: --show-transformed-name -f dist.tgz ./
Аргумент для передачи --xform имеет следующую структуру: s/regexp/replace/[flags]
Обратите внимание, что в моем примере я использовал :
как разделитель; Вы можете использовать любой символ, который хотите, если вы используете его последовательно. Хорошая ссылка здесь.
Есть несколько способов сделать это, на многие из которых уже намекали в этом вопросе, а некоторые - нет. Это моя попытка собрать их все (со ссылками) и показать примеры для удобного чтения, позволяя читателю выбрать тот, который соответствует его потребностям.
Пример дерева ввода
Это структура, которая будет описана в следующих примерах.
.dotfile
dir/
.hidden
file.txt
root.txt
Решение POSIX (кроссплатформенное, кросс-оболочка)
Вы можете использовать pax вместо tar, как указал Фил П.
Обычное поведение:
$ pax -wzvf ../ball.tar.gz .
[…]
$ pax -zf ../ball.tar.gz
.
./.dotfile
./dir
./dir/.hidden
./dir/file.txt
./root.txt
Без косой черты:
$ pax -wzvf ../ball.tar.gz -s ':^\./::' .
[…]
$ pax -zf ../ball.tar.gz
.
.dotfile
dir
dir/.hidden
dir/file.txt
root.txt
Shell Globbing (кросс-платформенное) решение
Вы также можете использовать *
вместо .
как указывал ott--. Это решение в основном является краткой формой ответа chutz, поскольку оболочка расширит звездочку в приведенном ниже примере на все не скрытые файлы, прежде чем передавать их в качестве аргументов tar
программа.
Без косой черты (но обратите внимание на отсутствие корневого уровня .dotfile
):
$ tar -czvf ../ball.tar.gz *
[…]
$ tar -tzf ../ball.tar.gz
dir/
dir/.hidden
dir/file.txt
root.txt
Если вам не нужно упаковывать точечные файлы в CWD, все готово.
Если вам все равно, вы не без защиты. На многих снарядах (например, bash
) можно включить точечные файлы в глобус оболочки, изменив параметр оболочки. С bash это делается с shopt:
dotglob
Если установлено, bash включает имена файлов, начинающиеся с "." в результатах расширения пути.
$ shopt -s dotglob # Include dot-files in pathname expansions
$ tar -czvf ../ball.tar.gz *
[…]
$ shopt -u dotglob # Restore shell's default globbing behavior
$ tar -tzf ../ball.tar.gz
.dotfile
dir/
dir/.hidden
dir/file.txt
root.txt
Решение GNU (Linux)
Используйте --xform, как упомянуто в ответе Джордана Бонитатиса.
Обычное поведение:
$ tar -czvf ../ball.tar.gz .
[…]
$ tar -tzf ../ball.tar.gz
./
./root.txt
./.dotfile
./dir/
./dir/file.txt
./dir/.hidden
Без косой черты:
$ tar -czvf ../ball.tar.gz --xform 's:^\./::' . [--show-transformed-names|--show-stored-names]
[…]
$ tar -tzf ../ball.tar.gz
./
root.txt
.dotfile
dir/
dir/file.txt
dir/.hidden
Решение BSD (Mac OS X)
Используйте -s, который обманчиво похож на pax / sed, но не совсем, как показано ниже.
Обычное поведение:
$ tar -czvf ../ball.tar.gz .
[…]
$ tar -tzf ../ball.tar.gz
./
./.dotfile
./dir/
./root.txt
./dir/.hidden
./dir/file.txt
Без косой черты:
$ tar -czvf ../ball.tar.gz -s '/.//' .
tar: Removing leading '/' from member names
[…]
$ tar -tzf ../ball.tar.gz
.dotfile
dir/
root.txt
dir/.hidden
dir/file.txt
Не уверен какая версия tar
это так, но обычно вы должны указать, какие файлы вы хотите архивировать. подобно tar c .
сжать все в локальном каталоге. Запустив вашу команду на моей машине, я получаю:
tar: Cowardly refusing to create an empty archive
Итак, если вы не хотите, чтобы получить ведущую ./
, что вы получаете, когда вы сжимаете локальный каталог .
Вы можете просто указать файлы напрямую. Например:
> tar c hosts fstab | tar tv
-rw-r--r-- root/root 1225 2012-10-20 13:37 hosts
-rw-r--r-- root/root 678 2012-05-13 22:09 fstab
Я использую это:
tar --create --directory a_dir $(ls --almost-all a_dir) > archive.tar
Это будет список всех файлов и каталогов (за исключением .
а также ..
) каталога a_dir
и добавить их в архив. --directory
options устанавливает корень, из которого tar начнет искать файлы.
В старых версиях tar он использовал полные пути, которые вы указали в tar, но это как-то проблематично, так как в старые времена форматирования может потребоваться вторая копия чего-либо и непреднамеренное расширение архива tar, может перезаписать существующий файл или файлы.
Таким образом, в самых последних версиях tar-бинарного файла, распространяемого практически в любом дистрибутиве Linux, знак./ ставится в начале каждого файла, который он упаковывает, так что непреднамеренное расширение расширяет архив в текущий рабочий каталог и ниже.
Я не уверен, почему это вызывает такую проблему для вас. если вы находитесь на нужном уровне каталогов, где вы хотите расширить этот архив, он сделает именно это. Например, допустим, у вас есть файл как
/tmp/myarchive.tar
и давайте предположим, что содержимое архива
./etc/hosts./etc/profile./etc/passwd./etc/group
если вы раскроете этот архив, пока ваш текущий рабочий каталог - / (то есть корневой уровень), эти файлы будут перезаписаны на существующие
/ и т.д. / хосты / И т.д. / профиль / И т.д. / пароль / И т.д. / группа
если это то, что вы хотите, у вас есть это. Но скажем, вы хотели, чтобы файлы хоста были только из этого архива, но внезапно вы стерли файлы профиля passwd и group. Надеюсь, у вас есть хорошая резервная копия на данный момент, чтобы вы могли получить их обратно
Но, если вы относитесь к типу системного администратора, который избегает находиться на корневом уровне, если он / она не нуждается в этом намеренно, скорее всего, вы вошли в систему и расположены в каталоге / home / some-user, или если вы вошли в систему как пользователь root, вы находятся в / корневой каталог. Допустим, ваш in / root. когда вы выполняете команду
# tar -xvf /tmp/myarchive.tar
вы закончите с
/ корень / и т.д. / хосты / Корень / и т.д. / профиль / Корень / и т.д. / пароль / Корень / и т.д. / группа
нет вреда, нет фола. затем
# mv /root/etc/hosts /etc/hosts
Вуаля. Вы достигли своей цели.
Я использовал tar -P
сохранить ведущие /
(скорее, чем ./
) Не совсем понятно, поможет ли это в вашем случае.
-P, --absolute-names
don't strip leading '/'s from file names