Intereting Posts
Невозможно увидеть Fedora 20, когда он загружает три раза с Debian 7 и openSuSe 13.1 Эквивалент Emacs <Cl> vim Символическая ссылка и вопросы с жесткой ссылкой Как избежать создания корневой папки источника в получателе при использовании rsync? awk помещает последний столбец в новую строку Отключение параметров упрощения безопасности для среды `nix-shell` GParted не находит раздел в зашифрованном диске Где находится файловая система «tmpfs»? Используйте sed для извлечения переменной из 1 файла и поместите ее в другую apt-get build-dep не может найти исходный пакет Функциональность Drag'n'Drop-Execute в KDE Как искать пакеты, которые больше не доступны для установки? Скрипт с завитом работает вручную, но не в работе cron Контрольный список с использованием whiptail – Почему я не могу запускать несколько команд? Неожиданное поведение файлового дескриптора и / или потоков ввода-вывода после запуска sqlcmd с ключом -i (чтение sql из файла) в ksh создает бесконечный цикл

Правильный синтаксис для включения. * Каталогов с tar

Я пытаюсь включить файлы, которые соответствуют */*/.thisdirectory/* в tar-архиве. Какой правильный синтаксис? По-видимому, это не так:

 > find . . ./bar ./bar/.a ./bar/.a/baz ./foo ./foo/.a > tar --include "*[.]a*" -cvf a.tar . > 

Я предполагаю, что вы используете FreeBSD tar¹, поскольку это единственная реализация, которую я знаю с помощью опции --include .

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

Чтобы добраться до каталогов .a , вам нужно будет включить все родительские каталоги. Дело в том, что если вы это сделаете, то все их содержимое также будет включено. Вы можете использовать --exclude чтобы исключить их, но тогда вам нужен шаблон исключения, который не исключает точечные каталоги, которые вы хотите включить. На данный момент --include больше не используется. Параметр --include редко используется при создании архива, он более полезен при копировании части существующего архива (потому что при этом нет рекурсивного обхода, просто итерации по списку элементов входного архива).

 tar --exclude='./*/[!.]*' -cvf a.tar . 

Обратите внимание, что все файлы в каталоге toplevel включены. Я не думаю, что есть способ включить только те каталоги, которые будут иметь непустое содержимое.

Чтобы получить только директории ./*/.* и ничего больше (в частности, не их родительские каталоги), вам нужно передать их как аргументы tar, а не позволить tar recurse их находить.

 tar -cvf a.tar ./*/.[!.]*/ 

Удалите конечную косую черту, чтобы включить файлы, которые не являются каталогами (или символическими ссылками на каталоги). Добавьте ./*/..?*/ чтобы включить каталоги, чье имя начинается с .. если у вас есть.

¹ Возможно, в другой операционной системе.

Если ваша оболочка bash, вы можете использовать переменную GLOBIGNORE чтобы скрыть . и .. каталоги. Это автоматически также устанавливает параметр dotglob , поэтому * теперь соответствует как скрытым, так и не скрытым файлам:

 GLOBIGNORE=".:.." tar czf tarball-with-hidden-files.tgz directory/* 

Для этого немного: по умолчанию * не соответствует скрытым файлам (файлы, начинающиеся с . ), Который включает в себя текущие ( . ) И родительские ( .. ) каталоги любого каталога. Если вы хотите, чтобы glob (например, групповой символ командной строки) соответствовал им, вам нужно установить опцию dotglob , но это может привести к тому, что действительно произойдет что- то плохое, если .. соответствует * и вы делаете что-то вроде rm -fr /home/olduser/* (потому что olduser/.. , который является /home/ и теперь вы только что GLOBIGNORE все домашние каталоги. В этом случае GLOBIGNORE вступает в GLOBIGNORE – он черным списком от подстановочных знаков. В качестве очень простого GLOBIGNORE использования:

 ghoti@home:~/scratch$ ls -ld ?dotfile ls: cannot access '?dotfile': No such file or directory ghoti@home:~/scratch$ touch _dotfile .dotfile ghoti@home:~/scratch$ ls -ld ?dotfile -rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile ghoti@home:~/scratch$ GLOBIGNORE=".:.." ghoti@home:~/scratch$ ls -ld ?dotfile -rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile -rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 .dotfile 

Что это значит для тебя? Ну, как в GLOBIGNORE примере в верхней части этого ответа, как только вы установите GLOBIGNORE на игнорирование . и .. , вы можете использовать * для сопоставления скрытых каталогов, таких как те, которые вы пытаетесь архивировать:

 tar czf mytarball.tgz directory/* # this will include things like directory/.hiddenfile 

Чтобы указать это на ваш конкретный пример каталога с именем .a :

 ghoti@home:~/scratch$ mkdir -p example example/foo/.a example/bar/.a example/foo/_a example/bar/_a ghoti@home:~/scratch$ touch example/{foo,bar}/{.,_}a/file ghoti@home:~/scratch$ find example/ example/ example/foo example/foo/_a example/foo/_a/file example/foo/.a example/foo/.a/file example/bar example/bar/_a example/bar/_a/file example/bar/.a example/bar/.a/file ghoti@home:~/scratch$ GLOBIGNORE=".:.." ghoti@home:~/scratch$ tar cvzf withdotfiles.tgz example/*/?a example/bar/_a/ example/bar/_a/file example/bar/.a/ example/bar/.a/file example/foo/_a/ example/foo/_a/file example/foo/.a/ example/foo/.a/file ghoti@home:~/scratch$ unset GLOBIGNORE ghoti@home:~/scratch$ tar cvzf withoutdotfiles.tgz example/*/?a example/bar/_a/ example/bar/_a/file example/foo/_a/ example/foo/_a/file