Ответы:
Отказ от ответственности: Этот ответ касается конкретно 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 , которая недопустимое имя опции для Баша .