Результат ls *, ls ** и ls ***

Я знаю использование команды ls перечислит все каталоги. Но что делает ls * команда делает? Я использовал его, и это просто перечисляет каталоги. Делает звезду перед ls имейте в виду, как глубоко это перечислит каталоги?

85
30.12.2019, 20:28
5 ответов

ls перечисляет файлы и содержание каталогов, оно передается как аргументы, и если никакой аргумент не дан, оно перечисляет текущий каталог. Это может также быть передано много опций, которые влияют на его поведение (см. man ls для деталей).

Если ls передается названный аргумент *, это будет искать названный файл или каталог * в текущем каталоге и списке это точно так же, как любой другой. ls не рассматривает * символ любым другим способом, чем кто-либо другой один.

Однако, если ls * командная строка оболочки, затем оболочка развернет это * согласно globbing соответствующей оболочки (также называемый Расширением Поколения или Имени файла Имени файла) правила.

В то время как различные оболочки поддерживают различные globbing операторы, большинство из них договаривается о самом простом *. * поскольку шаблон означает любое количество символов, таким образом, * как a glob развернет до списка файлов в текущих каталогах то соответствие тот шаблон. Существует исключение однако что ведущая точка (.) символ в имени файла должен быть подобран явно, таким образом, * на самом деле расширяется до списка файлов и каталогов, не запускающихся с . (в лексикографическом порядке).

Например, если текущий каталог содержит названные файлы ., .., .foo, -l и foo bar, * будет расширен оболочкой до двух аргументов для передачи ls: -l и foo bar, таким образом, это будет, как будто Вы ввели:

ls -l "foo bar"

или

'ls' "-l" foo\ bar

Которые являются тремя способами выполнить точно ту же команду. Во всех 3 случаях, ls команда (который будет, вероятно, выполняться от /bin/ls от поиска каталогов, упомянутых в $PATH) будет передан те 3 аргумента: "ls", "-l" и "панель нечто".

Кстати, в этом случае, ls будет рассматривать первое (строго говоря второй) один как опция.

Теперь, как я сказал, различные оболочки имеют различные globbing операторы. Несколько десятилетий назад, zsh представленный **/ оператор ¹, что означает соответствовать любому уровню подкаталогов, коротких для (*/)# и ***/ который является тем же за исключением того, что оно следует за символьными ссылками при убывании каталогов.

Несколько лет назад (июль 2003, ksh93o+), ksh93 решенный для копирования того поведения, но решил сделать это дополнительным, и только покрыл ** случай (нет ***). Кроме того, в то время как ** один не было особенным в zsh² (просто означал то же как * как в других традиционных оболочках с тех пор ** средства любое количество символа, сопровождаемого любым количеством символов), в ksh93, ** предназначенный то же как **/* (так любой файл или каталог ниже текущего (исключая скрытые файлы).

bash скопированный ksh93 несколько лет спустя (февраль 2009, колотите 4.0), с тем же синтаксисом, но неудачным различием: удар ** был похож zsh ***, это - это, следовал за символьными ссылками при рекурсивном вызове в подкаталоги, который обычно является не, что Вы хотите это, делают и может иметь противные побочные эффекты. Это было частично зафиксировано в ударе 4.3 в этом, символьные ссылки все еще сопровождались, но рекурсия, остановленная там. Это было полностью зафиксировано в 5,0.

yash добавленный ** в версии 2.0 в 2008, включенный с extended-glob опция. Его реализация ближе к zshв этом ** один не является особенным. В версии 2.15 (2009) добавило это *** как в zsh и два из его собственных расширений: .** и .*** включать скрытых директоров при рекурсивном вызове (в zsh, D спецификатор шарика (как в **/*(D)) рассмотрит скрытые файлы и каталоги, но если Вы только хотите пересечь скрытых директоров, но не развернуть скрытые файлы, Вам нужно ((*|.*)/)#* или **/[^.]*(D)).

Оболочка рыбы также поддерживает **. Как более ранняя версия bash, это следует за символьными ссылками при убывании дерева каталогов. В той оболочке однако **/* не то же как **. ** больше расширение * это может охватить несколько каталогов. В fish, **/*.c будет соответствовать a/b/c.c но нет a.c, в то время как a**.c будет соответствовать a.c и ab/c/d.c и zsh **/.* например, должен быть записан .* **/.*. Там, *** понят как ** сопровождаемый * так то же как **.

tcsh также добавленный a globstar опция в V6.17.01 (май 2010) и поддержки оба ** и *** а-ля zsh.

Таким образом в tcsh, bash и ksh93, (когда соответствующая опция включена (globstar)) или fish, ** разворачивает все файлы и каталоги ниже текущего, и *** совпадает с ** для fish, пересекающая символьная ссылка ** для tcsh с globstar, и то же как * в bash и ksh93 (хотя не невозможно, что будущие версии тех оболочек также пересекут символьные ссылки).

Выше, Вы заметите потребность удостовериться, что ни одно из расширений не интерпретируется как опции. Для этого Вы сделали бы:

ls -- *

Или:

ls ./*

Существуют некоторые команды (это не имеет значения для ls) где второе предпочтительно с тех пор даже с -- некоторые имена файлов можно рассматривать особенно. Это имеет место - для большинства текстовых утилит, cd и pushd и имена файлов, которые содержат = символ для awk например. Предварительное ожидание ./ ко всем аргументам удаляет их особое значение (по крайней мере, для упомянутых выше случаев).

Нужно также отметить, что большинство оболочек имеет много опций, которые влияют на globbing поведение (как то, проигнорированы ли точечные файлы или нет, порядок сортировки, что сделать, если там не идет ни в какое сравнение...), видят также $FIGNORE параметр в ksh

Кроме того, в каждой оболочке, но csh, tcsh, fish и zsh, если globbing шаблон не соответствует никакому файлу, шаблон передается как нерасширенный аргумент, который вызывает беспорядок и возможно ошибки. Например, если нет никакого нескрытого файла в текущем каталоге

ls *

Будет на самом деле звонить ls с этими двумя аргументами ls и *. И как нет никакого файла вообще, таким образом, ни одно позвонившее * также, Вы будете видеть сообщение об ошибке от ls (не оболочка) как: ls: cannot access *: No such file or directory, который, как было известно, заставил людей думать, что это было ls это на самом деле разворачивало шарики.

Проблема еще хуже в случаях как:

rm -- *.[ab]

Если существует нет *.a ни *.b файл в текущем каталоге, затем Вы могли бы закончить тем, что удалили названный файл *.[ab] по ошибке (csh, tcsh, и zsh не сообщила бы никакая ошибка соответствия и не будет звонить rmfish не поддерживает [...] подстановочные знаки)).

Если Вы действительно хотите передать литерал * кому: ls, необходимо заключить это в кавычки * символ в некотором роде как в ls \* или ls '*' или ls "*". В подобных POSIX оболочках globbing может быть отключен в целом с помощью set -o noglob или set -f (последний не работа в zsh если в sh/ksh эмуляция).


¹, В то время как (*/)# всегда поддерживался, это было сначала неукомплектовано как ..../ в zsh-2.0 (и потенциально прежде), затем ****/ в 2,1 прежде, чем получить его категорическую форму **/ в 2,2 (в начале 1992)

² globstarshort опция, имеет с тех пор быть добавленным (в 2015) для разрешения ** и *** быть используемым вместо **/* и ***/* соответственно

156
27.01.2020, 19:30
  • 1
    Действительно большой ответ! –  Andrea Corbellini 26.01.2013, 19:57
  • 2
    ссылки Другой хороший пример find -name *. Особенно с более сложными шаблонами, если существует точно одно соответствие в текущем каталоге, люди не будут часто понимать, что они не передают звездочку find. –  njsg 27.01.2013, 12:57
  • 3
    , который я продолжаю давать +1, я действительно рад видеть Stephane Chazelas, активного здесь на unix.stackexchange.com! Большие вклады, Stephane, как всегда! –  Dimitre Radoulov 27.01.2013, 19:04
  • 4
    У рыбы, *.[ab] попытался бы удалить все заканчивающееся .[ab]. [ не является особенным у рыбы. –  Konrad Borowski 17.04.2014, 12:26

Команда ls значения по умолчанию к ls .: Перечислите все записи в текущем каталоге.

Команда ls * означает 'выполненный ls на расширении * шаблон оболочки'

* шаблон обрабатывается оболочкой и расширяется до всех записей в текущем каталоге, кроме тех, которые запускаются с a .. Это пойдет один уровень глубоко.

Интерпретация двойных или тройных * шаблоны зависят от фактической используемой оболочки.

* подстановочный знак, который соответствует 0 или больше символам. Некоторые современные оболочки рекурсивно вызовут в подкаталоги наблюдение ** шаблон.

36
27.01.2020, 19:30
  • 1
    За исключением того, что дополнительный * действительно добавьте что-то, см., что другой ответ объясняет globstar. Нужно также ясно дать понять, что ls не имеет никакого отношения к звездочкам, это никогда не передавало ни одной из этих звездочек вообще. Выполненный echo ls * видеть, что было бы выполнено, когда Вы пишете ls *. спасибо –  njsg 26.01.2013, 23:49

Можно демистифицировать целый процесс путем ввода echo вместо ls во-первых, для наблюдения то, до чего расширяется команда:

$ echo *
Applications Downloads Documents tmp.html

Так в этом случае, ls * расширяется до ls Applications Downloads Documents tmp.html

$ echo **
Applications Downloads Documents tmp.html

$ echo ***
Applications Downloads Documents tmp.html

Так никакое изменение. Это предполагает, что Вы используете bash как Ваша оболочка - большинство людей, и различные оболочки имеют другое поведение. Если Вы используете ash или csh или ksh или zsh, можно ожидать вещи работать по-другому. В этом суть наличия различных оболочек.

Так позволяет, пробуют что-то другое (все еще с bash) таким образом, мы понимаем globbing (*) оператор может сделать для нас. Например, мы можем отфильтровать частью имени:

$ echo D*
Downloads Documents

И интересно, запаздывающая наклонная черта неявно часть любого имени каталога. Так */ приведет только к каталогам (и символьные ссылки на каталоги):

$ echo */
Applications/ Downloads/ Documents/

И мы можем сделать некоторую фильтрацию на нескольких уровнях путем помещения наклонных черт в середине:

$ echo D*/*/
Documents/Work/ /Documents/unfinished/

Начиная с Downloads каталог не содержит подкаталогов, он не заканчивается в выводе. Это очень полезно для того, чтобы просто исследовать файлы, которые Вы хотите. Я использую команды как это все время:

$ ls -l /home/*/public_html/wp-config.php

Это перечисляет, если существует кто-либо, весь wp-config.php файлы, которые существуют на основном уровне любого пользователя public_html каталог. Или возможно быть больше завершенным:

$ find /home/*/public_html/ -name wp-config.php

Это найдет любого wp-config.php файлы в любом пользователе public_html каталоги или любой из их подкаталогов, но это будет работать более эффективно, чем просто find /home/ -name wp-config.php потому что это не исследует ничего, но public_html каталоги для каждого из пользователей.

12
27.01.2020, 19:30
  • 1
    "Это предполагает, что Вы используете bash как Ваша оболочка" ← и что globstar не включен. shopt -s globstar и попробуйте его снова... –  njsg 27.01.2013, 19:53

В некоторых оболочках, включая удар 4.x с globstar опция включила, ** выполнит рекурсивный шарик, убывающие подобранные каталоги. Дополнительные звездочки далее не изменяют эту операцию.

10
27.01.2020, 19:30
  • 1
    Как я сказал в своем ответе, хотя, остерегайтесь этого вопреки ksh93 и zsh, bash действительно пересекает символьные ссылки в рекурсии, которая обычно нежелательна. –  Stéphane Chazelas 26.01.2013, 23:12
  • 2
    Это было теперь зафиксировано в ударе 4.3 –  Stéphane Chazelas 18.03.2014, 15:47

Если Вы хотите "погрузиться глубоко", ls использования-R (рекурсивная) опция, или использование находит, как так:

find . -ls

"находка" погрузится вниз к нижней части дерева каталогов (как будет 'ls-R'), и имеет намного больше опций, как список каталогов (-типа d), файлы только (-тип f) или показ файлов, имеющих другие характеристики (никакой пользователь в/etc/passwd, определенных полномочиях, и намного больше). "находка" также несколько более безопасна в сценариях (из-за непоследовательных правил globbing между оболочками, а также специальных Escape для файлов, имеющих тире, и т.д.).

подстановочный знак оболочки globbing не будет работать только с звездочкой '*' на dotfiles. Для списка dotfiles только используйте:

ls .??*

0
27.01.2020, 19:30

Теги

Похожие вопросы