Ответы:
Отказ от ответственности: Этот ответ касается конкретно Bash, но большая часть его относится к вопросу о шаблонах глобуса!
Символ звезды ( *
) является подстановочным знаком. Есть определенный набор символов, который он заменит, и первый символ, являющийся точкой ( .
), не является одним из них. Это особый случай только из-за того, как работают файловые системы Unix, файлы, начинающиеся с точки, считаются «скрытыми». Это означает, что такие инструменты, как cp
,ls
и т. Д. Не будут «видеть» их, если явно не указано иное.
Сначала давайте создадим несколько примеров данных.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Итак, теперь у нас есть следующее:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Теперь давайте поиграем в некоторые игры. Вы можете использовать команду, echo
чтобы перечислить, какой будет подстановочный знак ( *
) для данной команды, например:
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
$ echo reg*
regdir1 regdir2 regfile1 regfile2 regfile3
$ echo .*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2
$ echo .* *
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
$ echo .dotdir*
.dotdir1 .dotdir2
Вы можете использовать команду, shopt -s dotglob
чтобы изменить поведение *
так, чтобы в дополнение к файлам, как regfile1
это также будет соответствовать.dotfile1
.
выдержка из bash
справочной страницы
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Пример:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Вы можете восстановить это поведение с помощью этой команды:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Для вас вы говорите, cp
что хотите скопировать все файлы, которые соответствуют шаблону *
, и нет никаких файлов.
$ cp foo/.* .
Или вы можете сделать это, если хотите все в foo
папке:
$ cp foo .
Или вы можете быть явным:
$ cp foot/.* foo/* .
Более компактная форма с использованием расширения скобки в bash
:
$ cp foo/{.,}* .
В любое время вы можете использовать echo
трюк, чтобы увидеть, какие у вас предложены шаблоны файлов (это причудливый термин для обозначения того, что является звездой).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
Кстати, если вы собираетесь скопировать каталог файлов + другие каталоги, вы, как правило, хотите сделать это рекурсивно, это -R
переключение на cp
:
$ cp -R foo/. .
shopt -s dotglob
, а echo *
затем дает:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
как правило, не будет работать, так cp
как откажется копировать foo
сам, вы, вероятно, подразумевали cp -R foo/. .
. (обратите внимание, что cp -R
это стандартный).
zsh
не включает .
и ..
в расширение .*
. В zsh
, если шаблон не соответствует, то команда прерывается (вполне здраво снова), так что в общем случае, cp foo/{,.}* .
не получится, если нет не скрыто или нет не-скрытых файлов.
shopt
не существует.
С zsh
типичным способом является использование D
спецификатора glob (для включения [D] ot файлов):
cp foo/*(D) .
Обратите внимание, что с или без D
, zsh-глобусы никогда не включают .
ни ..
(как вы ожидаете).
Оболочка обрабатывает эти файлы как скрытые, когда разрешает *
символ, поэтому cp
не получает ни одно из этих имен файлов в качестве аргументов.
Вы можете скопировать их, явно указав cp foo/.* .
Если вы хотите скопировать все файлы и каталоги из одного места в другое, вы можете использовать стандартную rsync
команду. В приведенном выше примере:
mkdir foo && touch foo/.test
rsync -a foo/ .
будет рекурсивно копировать все содержимое foo
, включая скрытые файлы и скрытые каталоги, в текущий каталог. Конечный слеш в конце foo/
важен для rsync; при этом foo
копируется только содержимое , без него также копируется rsync foo
. Например:-
mkdir src && mkdir dest && touch src/.test
rsync -a src dest // copies 'src' contents to 'dest/src'
rsync -a src/ dest // copies 'src' contents to 'dest'
Есть много других доступных опций настройки rsync, включая копирование между компьютерами.
dotglob
транслируютсяglobdots
по Zsh , которая недопустимое имя опции для Баша .