2

Я заметил, что всякий раз, когда я использую команду cp -R foo/* я копирую все, кроме файлов, таких как .env или, возможно, .gitignore

Решение состоит в том, чтобы использовать cp -R foo/ поскольку он управляет всем каталогом, но это не меняет того факта, что я до сих пор не понимаю поведение использования символа * .

Почему символ * не может поймать такие файлы, как .env?

ОС Debian

3 ответа3

5
  • cp -R foo/ рекурсивно копирует все под foo/
  • cp -R foo/* рекурсивно копирует все файлы и каталоги, которые соответствуют foo/* . И по умолчанию имена с точкой не включаются (ls * также не перечисляет их). Это объясняется здесь (а также некоторые другие мелкие детали о ведущих точках).

Помимо обработки файлов с начальными точками, другое отличие состоит в том, что cp -R foo/* копирует отдельные файлы и каталоги в foo/ в целевой каталог, а cp -R foo/ делает копию foo/ в целевом каталоге ( так что вы получите еще один уровень каталогов).

3

По умолчанию глобализация в bash не включает имена файлов, начинающиеся с . Поэтому, когда вы указываете * вы запрашиваете рекурсивное копирование без файлов, начинающихся с " . ". Когда вы не указываете * он копирует все, включая файлы " . ".

2

В дополнение к другим имеющимся у вас ответам, есть несколько других случаев, когда foo/ и foo/* могут отличаться (не только файлы, начинающиеся с .). Кроме того, если вы хотите иметь файлы, которые начинаются с . в соответствии с вашим глобусом, вы также можете включить это с shopt -s dotglob .

Во-первых, если в foo/ нет записей и вы не включили nullglob то foo/* будет возвращен как литерал, передаваемый в cp . Поскольку (в данном случае) нет источника, foo/* cp будет жаловаться, в то время как cp -R foo/ всегда будет иметь по крайней мере foo/ для копирования. Если бы вы nullglob то foo/* расширился бы до нуля, так что в итоге вы пропустили бы аргумент cp .

Другой случай, который нужно рассмотреть, - это если в foo/ записей. Оболочка расширяет глоб и затем вызывает процесс, но если глоб расширяется до слишком большого количества аргументов, вы получите ошибку. С cp -R foo/ вас есть только 2 аргумента (хотя, вероятно, у вас будет цель где-то еще).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .