Я знаю, что с помощью команды ls
будут перечислены все каталоги. Но что делает ls *
команда? Я использовал это, и это просто перечисляет каталоги. Звезда перед значком ls
означает, насколько глубоко она может перечислить каталоги?
ls
перечисляет файлы и содержимое каталогов, которые передаются в качестве аргументов, и если аргумент не задан, в нем отображается текущий каталог. Также может быть передан ряд опций, которые влияют на его поведение (подробнее см. man ls
).
Если ls
передается вызываемый аргумент *
, он будет искать файл или каталог, вызываемый *
в текущем каталоге, и перечислять его, как и любой другой. ls
не относится к *
персонажу каким-либо иным способом, кроме как к другому.
Однако , если ls *
это оболочка командной строки, то оболочка будет расширяться , что в *
соответствии с соответствующей оболочечному подстановка (также упоминается как Filename Generation или Filename Expansion ) правил.
В то время как разные оболочки поддерживают разные операторы глобализации, большинство из них соглашаются на самый простой *
. *
под шаблоном подразумевается любое количество символов, поэтому *
a glob
расширится до списка файлов в текущих каталогах, которые соответствуют этому шаблону. Однако есть исключение, что начальный .
символ точки ( ) в имени файла должен явно совпадать, поэтому *
фактически расширяется до списка файлов и каталогов, не начиная с .
(в лексикографическом порядке).
Например, если текущий каталог содержит файлы , называемые .
, ..
, .foo
, -l
и foo bar
, *
будет расширен за счет оболочки двух аргументов для передачи ls
: -l
и foo bar
, таким образом , это будет , как если бы вы ввели:
ls -l "foo bar"
или же
'ls' "-l" foo\ bar
Какие три способа выполнить одну и ту же команду? Во всех трех случаях ls
команде (которая, вероятно, будет выполнена из /bin/ls
поиска в каталогах, упомянутых в $PATH
), будут переданы эти 3 аргумента: «ls», «-l» и «foo bar».
Кстати, в этом случае ls
первый (строго говоря, второй ) будет рассматриваться как вариант.
Теперь, как я уже сказал, у разных оболочек разные операторы сглаживания. Несколько десятилетий назад был zsh
введен **/
оператор¹, который означает соответствие любому уровню подкаталогов, сокращенному (*/)#
и ***/
который одинаков, за исключением того, что он следует по символическим ссылкам при спуске каталогов.
Несколько лет назад (июль 2003 г. ksh93o+
) ksh93
решили скопировать это поведение, но решили сделать его необязательным и рассмотрели только **
случай (не ***
). Кроме того, хотя **
один не был особенным в zsh
(просто означал то же самое, что *
и в других традиционных оболочках, поскольку **
означает любое количество символов, за которым следует любое количество символов), в ksh93 **
означал то же самое, что **/*
(поэтому любой файл или каталог ниже текущего (исключая скрытые файлы).
bash
скопировал ksh93
несколько лет спустя (февраль 2009 г., bash 4.0), с тем же синтаксисом, но прискорбным отличием: bash **
был похож zsh
на s ***
, то есть он следовал по символическим ссылкам при повторном обращении в подкаталоги, что обычно не то, что вы хотите, и может иметь неприятные побочные эффекты. Это было частично исправлено в bash-4.3, так как символические ссылки все еще использовались, но рекурсия на этом остановилась. Это было полностью исправлено в 5.0.
yash
добавлен **
в версии 2.0 в 2008 году, включен с extended-glob
опцией. Его реализация ближе к тому zsh
, что **
только в этом нет ничего особенного. В версии 2.15 (2009), добавил он , ***
как в zsh
и два собственных расширений: .**
и .***
включить скрытые каталоги при рекурсии (в zsh
, то D
Глоб классификатор (как **/*(D)
) будет рассматривать скрытые файлы и папки, но если вы хотите , чтобы пройти скрытый dirs но не раскрывайте скрытые файлы, вам нужно ((*|.*)/)#*
или **/[^.]*(D)
).
Ракообразные также поддерживает **
. Как и в предыдущей версии bash
, он следует по символическим ссылкам при спуске по дереву каталогов. В этой оболочке, однако **/*
, не то же самое, что **
. **
это расширение, *
которое может охватывать несколько каталогов. В fish
, **/*.c
будет соответствовать , a/b/c.c
но не a.c
, в то время как a**.c
будет соответствовать a.c
и ab/c/d.c
и zsh
«s **/.*
, например , должно быть написано .* **/.*
. Там ***
понимается как **
следует *
так же, как и **
.
tcsh
также добавлена globstar
опция в V6.17.01 (май 2010 г.) и поддерживается как **
и ***
а-ля zsh
.
Так tcsh
, bash
и ksh93
(если соответствующая опция ( globstar
)) или fish
, **
разворачивает все файлы и каталоги ниже текущего, и ***
такая же , как **
для fish
, символьной ссылки , пересекающей **
для tcsh
с globstar
, и так же , как *
в bash
и ksh93
(хотя это не исключено, что будущие версии этих оболочек будут также проходить по символическим ссылкам).
Выше вы заметили необходимость убедиться, что ни одно из расширений не интерпретируется как опция. Для этого вы должны сделать:
ls -- *
Или же:
ls ./*
Есть некоторые команды (это не имеет значения ls
), где вторая предпочтительнее, поскольку даже с --
некоторыми именами файлов могут быть обработаны специально. Это дело -
для большинства текстовых утилит, cd
а pushd
и имена файлов , которые содержат =
символ для awk
, например. Приставка ./
ко всем аргументам убирает их особое значение (по крайней мере, для случаев, упомянутых выше).
Следует также отметить, что большинство оболочек имеют ряд опций, которые влияют на поведение сглаживания (например, игнорируются ли точечные файлы, порядок сортировки, что делать, если нет совпадений ...), см. Также $FIGNORE
параметр вksh
Кроме того , в любой оболочке , но csh
, tcsh
, fish
и zsh
, если подстановка шаблон не соответствует любому файлу, шаблон передается в качестве аргумента нераскрытого , что вызывает путаницу и , возможно , ошибку. Например, если в текущем каталоге нет скрытого файла
ls *
На самом деле позвонит ls
с двумя аргументами ls
и *
. И так как файла нет вообще, поэтому ни один из них не вызван *
, вы увидите сообщение об ошибке от ls (не от оболочки) вроде:, ls: cannot access *: No such file or directory
который, как известно, заставляет людей думать, что это ls
действительно расширяет глобусы.
Проблема еще хуже в таких случаях, как:
rm -- *.[ab]
Если нет никакого , *.a
ни *.b
файл в текущем каталоге, то вы можете в конечном итоге удалить файл с именем *.[ab]
по ошибке ( csh
, tcsh
и zsh
будет сообщать не ровня ошибку и не назвал бы rm
(и fish
не поддерживает [...]
подстановочные знаки)).
Если вы хотите передать литерал *
в ls
, вы должны указать этот *
символ каким-либо образом, например, в ls \*
или ls '*'
или ls "*"
. В POSIX-подобных оболочках глобализация может быть полностью отключена с помощью set -o noglob
или set -f
(последняя не работает, zsh
если в sh
/ ksh
эмуляции).
¹ Хотя (*/)#
это всегда поддерживалось, сначала оно было коротким, как ..../
в zsh-2.0 (и, возможно, раньше), затем ****/
в 2.1, прежде чем получить окончательную форму **/
в 2.2 (начало 1992 года).
find -name *
. Особенно с более сложными шаблонами, если в текущем каталоге есть только одно совпадение, люди часто не поймут, что не передают звездочкуfind
.*.[ab]
попытался бы удалить все, заканчивающиеся на.[ab]
.[
не особенный в рыбе.Команда по
ls
умолчаниюls .
: Список всех записей в текущем каталоге .Команда
ls *
означает «запустить ls при расширении*
шаблона оболочки»*
Шаблон обрабатывается оболочкой, и расширяется до всех записей в текущем каталоге, за исключением тех , которые начинаются с.
. Это пойдет на один уровень глубже.Интерпретация двойных или тройных
*
паттернов зависит от фактической используемой оболочки.*
подстановочный знак, который соответствует 0 или более символов. Некоторые современные оболочки будут видны в подкаталогах при просмотре**
шаблона.источник
*
действительно добавить что-то, см. Другой ответ, объясняющий Globstar. Следует также прояснить, что ls не имеет ничего общего со звездочками, он никогда не пропускает ни одну из этих звездочек. Запустите,echo ls *
чтобы увидеть, что будет выполнено, когда вы напишитеls *
.Вы можете демистифицировать весь процесс, набрав
echo
вместоls
первого, чтобы увидеть, к чему относится команда:Так что в этом случае
ls *
расширяется доls Applications Downloads Documents tmp.html
Так что без изменений. Это предполагает, что вы используете в
bash
качестве оболочки - большинство людей, и разные оболочки имеют разное поведение. Если вы используетеash
илиcsh
илиksh
илиzsh
, вы можете ожидать, что все будет работать по-другому. Вот в чем смысл наличия разных оболочек.Итак, давайте попробуем что-то другое (все еще с
bash
), чтобы мы могли понять, что*
оператор globbing ( ) может сделать для нас. Например, мы можем фильтровать по части имени:И что интересно, завершающий слеш неявно является частью любого имени каталога. Таким образом,
*/
будут выдаваться только каталоги (и символические ссылки на каталоги):И мы можем сделать некоторую фильтрацию на нескольких уровнях, поместив косую черту в середине:
Поскольку
Downloads
каталог не содержит никаких подкаталогов, он не попадает в вывод. Это очень полезно только для изучения файлов, которые вы хотите. Я все время использую такие команды:В этом списке перечислены все
wp-config.php
файлы, которые существуют на базовом уровне вpublic_html
каталоге любого пользователя . Или, возможно, чтобы быть более полным:Это позволит найти любые
wp-config.php
файлы в любого пользователяpublic_html
каталогов или любой из их подкаталогов, но он будет работать более эффективно , чем простоfind /home/ -name wp-config.php
потому , что он не будет ничего исследовать , но вpublic_html
каталогах для каждого из пользователей.источник
bash
качестве оболочки» ← и что globstar не включен.shopt -s globstar
и попробуйте снова ...set -x
том, чтобы начать печатать «фактическую» команду, выполняемую каждый раз (выключить с помощьюset +x
).В некоторых оболочках, включая bash 4.x с
globstar
включенной опцией,**
будет выполняться рекурсивный глобус, нисходящий совпадающий каталог. Дополнительные звездочки больше не изменяют эту операцию.источник
ksh93
иzsh
,bash
пересекает символические ссылки в рекурсии, которая обычно нежелательна.Если вы хотите "погрузиться глубже", используйте опцию ls -R (recursive) или используйте find, например так:
«find» опустится до нижней части дерева каталогов (как и «ls -R») и имеет много других опций, таких как перечисление каталогов (-type d), только файлов (-type f) или показ файлов, имеющих другие характеристики (нет пользователя в / etc / passwd, особые права и многое другое). «find» также несколько безопаснее в сценариях (из-за непоследовательных правил подстановки между оболочками, а также из-за специальных экранирований для файлов с тире и т. д.).
Подстановочные символы оболочки не будут работать с звездочкой '*' в точечных файлах. Чтобы перечислить только точечные файлы, используйте:
ls .??*
источник
Extra * не добавляет уровень глубины. Но если вы попробуете
- вы получите список подпапок подпапок в папках в текущей папке ...
источник
*
s добавят уровень глубины.bash
с опцией globstar, оболочку korn и zsh. И, возможно, другие, я думаю. unix.stackexchange.com/a/62665/14831Мое основное преимущество заключается в том, что echo ** / *. Ext обычно ...
Может или не может: перечислить файл .ext в текущем каталоге
Может или не может: включить. *. Ext файлы
Как правило, я бы предпочел, чтобы выражение glob было '** /' и могло привести к пустой строке (без подкаталога). Вот как я конвертирую выражения glob в программный ввод. Конечно, я уверен, что есть комментарии, объясняющие это в примерах использования.
источник