tar czf dist.tgz --exclude = ". gitignore".
Это создает файлы в tar с начальным "./", что позже превращается в проблему, когда серверу необходимо извлечь части tar.
Может ли кто-нибудь сказать мне, как его упаковать, чтобы не было ведущего "./"?
Попробуйте --xform
option, который использует выражение замены, подобное 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 -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-- указал. Это решение представляет собой сокращенную форму наглости ответ, поскольку оболочка расширит звездочку в приведенном ниже примере на все не скрытые файлы, прежде чем передавать их в качестве аргументов в tar
программа.
Нет точки-косой черты (но обратите внимание на отсутствие корневого уровня .dotfile
):
$ tar -czvf ../ball.tar.gz *
[…]
$ tar -tzf ../ball.tar.gz
dir/
dir/.hidden
dir/file.txt
root.txt
Если вы не заботитесь об упаковке точечных файлов в CWD, все готово.
если ты делать забота, у тебя есть выход. На многих оболочках (например, bash
) можно включить точечные файлы в глобус оболочки, изменив параметр оболочки. В bash это делается с помощью купил:
dotglob
Если установлено, трепать включает имена файлов, начинающиеся с символа '.' в результатах раскрытия имени пути.
$ 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, что обманчиво похоже на человек/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 -P
сохранить ведущую /
(скорее, чем ./
Не совсем понятно, поможет ли это в вашем случае.
-P, --absolute-names
don't strip leading '/'s from file names
В старых версиях tar он использовал полные имена путей, которые вы указали в tar, но это как-то проблематично, так как может понадобиться вторая копия чего-то и непреднамеренное расширение tar-архива в дни старого формата, может перезаписать существующий файл или файлы.
Таким образом, в самых последних версиях двоичного файла tar, распространяемого практически в любом дистрибутиве Linux, в начале каждого файла, который он упаковывает, помещается ./, так что при непреднамеренном расширении архив расширяется до вашего текущего рабочего каталога и ниже.
Я не уверен, почему это вызывает у вас такую проблему. если вы находитесь на правильном уровне каталога, куда вы хотите расширить этот архив, он сделает именно это. Например, допустим, у вас есть файл как
/tmp/myarchive.tar
и предположим, что содержимое архива
./etc/hosts ./etc/profile ./etc/passwd ./etc/group
если вы расширите этот архив, пока ваш текущий рабочий каталог находится на / (т.е. на корневом уровне), эти файлы перейдут и перезапишут существующий
/etc/hosts /etc/profile /etc/passwd /etc/group
если это то, что вы хотите, вы это получили. Но предположим, вы хотели только файлы hosts из этого архива, но внезапно вы стерли пароль профиля и файлы группы. Надеюсь, у вас есть хорошая резервная копия, чтобы вы могли вернуть их
Но, если вы относитесь к типу системного администратора, который избегает использования корневого уровня, если он / она не нуждается в этом намеренно, вы, скорее всего, вошли в систему, расположенную в / home / some-user, или если вы вошли в систему как root, вы находятся в корневом каталоге. Допустим, ваш in / root. когда вы выполняете команду
# tar -xvf /tmp/myarchive.tar
вы закончите с
/root/etc/hosts /root/etc/profile /root/etc/passwd /root/etc/group
без вреда, без фола. затем
# mv /root/etc/hosts /etc/hosts
Вуаля. Вы добились своей цели.
Я использую это:
tar --create --directory a_dir $(ls --almost-all a_dir) > archive.tar
Это будет список всех файлов и каталогов (кроме .
и ..
) каталога a_dir
и добавляем их в архив. В --directory
options устанавливает корень, с которого tar будет искать файлы.