почему делает ls-d, также перечисляют файлы, и где он документируется?

Касаясь того, что уже сказал @Juliano.

Контроль posix_fadvise если настоящей проблемой является недостойное поведение алгоритма кэширования базовой файловой системы, можно ли попробовать, дают ему совет, как Вы собираетесь использовать файловую систему. В течение приятно реализованной фс это должно дать повышение производительности. (Вот ссылка на другую тему, касающуюся подобных соображений https://stackoverflow.com/a/3755818/544721),

48
09.05.2013, 07:49
7 ответов

a* и *a* синтаксис реализован оболочкой, не ls команда.

Когда Вы вводите

ls a*

при Вашем приглашении оболочки расширяется оболочка a* к списку существующих все файлы в текущем каталоге, имена которого запускаются с a. Например, это могло бы расшириться a* к последовательности a1 a2 a3, и передайте тех, которые как аргументы ls. ls сама команда никогда не видит * символ; это только видит эти три аргумента a1, a2, и a3.

В целях подстановочного расширения "файлы" относятся ко всем объектам в текущем каталоге. Например, a1 мог бы быть нормальный файл, a2 мог бы быть каталог, и a3 могла бы быть символьная ссылка. У них всех есть записи каталога, и подстановочное расширение оболочки не заботится, к какому объекту те записи относятся.

Практически все оболочки Вы, вероятно, будете натыкаться (удар, sh, ksh, zsh, csh, tcsh...) на подстановочные знаки реализации. Детали могут варьироваться, но базовый синтаксис * соответствие нулю или большему количеству символов и ? соответствие любому отдельному символу довольно последовательно.

Для удара в частности, это документируется в раздел "Filename expansion" руководства удара; выполненный info bash и поиск "Расширения имени файла", или видят здесь.

То, что это сделано оболочкой, а не отдельными командами, имеет некоторых интересных (и иногда удивляющий) последствия. Лучшая вещь об этом состоит в том, что подстановочная обработка последовательна для (очень почти) все команды; если бы оболочка не сделала этого, то неизбежно некоторые команды не обеспокоились бы, и другие сделали бы это тонко различными способами, которыми думал автор, было "лучше". (Я думаю, что командный процессор Windows имеет эту проблему, но я не достаточно знаком с ним для комментария далее.)

С другой стороны, трудно записать команду для переименования нескольких файлов. Если Вы пишете:

mv *.log *.log.bak

это, вероятно, перестанет работать с тех пор*.log.bak расширен на основе файлов, которые уже существуют в текущем каталоге. Существуют команды, которые делают такого рода вещь, но они должны использовать свой собственный синтаксис, чтобы указать, как файлы должны быть переименованы. Некоторые команды (такой как find) может сделать их собственное подстановочное расширение; необходимо заключить аргументы в кавычки для подавления расширения оболочки:

find . -name '*.txt' -print

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

mv *.log ..

Если Вы забываете .. :

mv *.log

и, оказывается, существуют точно два .log файлы в текущем каталоге, это расширится до:

mv one.log two.log

который переименует one.log и ударьте two.log.

Править: И после 52 upvotes, принятия и значка Гуру, возможно, я должен на самом деле ответить на вопрос в заголовке.

-d или --directory опция к ls не говорит этому перечислять только каталоги. Это говорит этому перечислять каталоги так же, как сами, не их содержание. Если Вы даете имя каталога как аргумент ls, по умолчанию это перечислит содержание каталога, так как это обычно, чем Вы интересуетесь. -d опция говорит этому перечислять просто сам каталог. Это может быть особенно полезно в сочетании с подстановочными знаками. Если Вы вводите:

ls -l a*

ls даст Вам длинный список каждого файла, имя которого запускается с a, и содержания каждого каталога, имя которого запускается с a. Если Вы просто хотите список файлов и каталоги, одну строку для каждого, можно использовать:

ls -ld a*

который эквивалентен:

ls -l -d a*

Помните снова что ls команда никогда не видит * символ.

Что касается того, где это документируется, man ls покажет Вам документацию для ls команда в примерно любой подобной Unix системе. В большинстве основанных на Linux систем, ls команда является частью GNU coreutils пакет; если Вы имеете info команда, также info ls или info coreutils ls должен дать Вам более категорическую и подробную документацию. Другие системы, такие как MacOS, могут использовать различные версии ls команда, и не может иметь info команда; для тех систем использовать man ls. И ls --help покажет относительно короткое сообщение использования (117 строк в моей системе), если Вы будете использовать GNU coreutils реализация.

И да, даже эксперты должны консультироваться с документацией время от времени. Понимаете также эту классическую шутку.

90
27.01.2020, 19:34
  • 1
    @Thomas взлома Google Earth: a* расширяется до списка всех файлов в текущем каталоге, имена которого запускаются с a. –  Keith Thompson 08.05.2013, 04:58
  • 2
    @Thomas: Или в любом каталоге Вы указываете:ls subdir/a* –  Keith Thompson 08.05.2013, 09:26
  • 3
    Действительно видеть команду, выполняемую после расширения оболочки, echo это. Таким образом, если Вы хотите знать то, что происходит, когда Вы делаете ls a*, сначала выполнитесь echo ls a* –  Carlos Campderrós 08.05.2013, 13:04
  • 4
    или просто echo a* ... оболочка делает расширение шарика так или иначе –  Useless 08.05.2013, 19:47
  • 5
    @sendmoreinfo: Это зависит от оболочки и настроек. В csh и tcsh, провальное расширение шарика является ошибкой. В ударе, shopt -s failglob вызывает то же поведение. Установка nullglob но нет failglob причины, например, *nosuchfile* расшириться до пустой строки. –  Keith Thompson 08.05.2013, 21:34

См. ответ Keith Thompson; но объяснить, почему ls --directory a* выставочные файлы и каталоги: --directory опция не подавляет файлы некаталога. Вместо этого это перечисляет каталоги как таковые, в то время как это иначе перечислило бы их содержание. Пример:

$ mkdir foo
$ touch foo/bar
$ ls foo
bar
$ ls --directory foo
foo
27
27.01.2020, 19:34
  • 1
    , что пример более востребован с -F опция –  glenn jackman 08.05.2013, 05:18

Чтобы быть очень явным, это документируется в ls (1) страница руководства:

- d, - записи каталога списка каталога вместо содержания, и не разыменовывают символьные ссылки

для ярмарки, "записи вместо содержания" могли, вероятно, быть более объяснительными:

Если ФАЙЛ является каталогом, покажите саму запись каталога вместо того, чтобы перечислить содержание того каталога. Если ФАЙЛ является символьной ссылкой, покажите саму запись ссылки вместо файла, на который указывает ссылка.

6
27.01.2020, 19:34
  • 1
    Чтобы быть педантичным, в то время как-d опция может быть объяснена (если кратко) в странице справочника, расширении аргумента и wildcarding не документируется в ls страницу справочника, так как это сделано оболочкой. Если бы Вы выключили расширение имени файла в своей оболочке, то "ls*" только показал бы Вам файл, которым это буквально называют '*'. –  Johnny 08.05.2013, 09:10
  • 2
    Чтобы быть педантичным, в то время как расширению оболочки ответили другие респонденты, ни один из них не обращается к скудному объяснению и как оно могло бы неправильно читаться. Если Вы хотели бы, чтобы я повторил, что, который был уже хорошо сказан, являются более прямыми. –  msw 08.05.2013, 12:45

Globbing

Как был объяснен, расширение * (и подобные расширения), назван globрезкий звук на жаргоне Unix, и обычно является функцией командного процессора (известный как "оболочка" в языке Unix). Таким образом, globbing может использоваться во многих других местах также; ввести man 7 glob в оболочке классического дистрибутива Linux (или посмотрите это) для больше о globрезкий звук.

В раннем Unix, glob был на самом деле реализован отдельной названной программой /etc/glob (см. страницу 10 этого старого руководства UNIX для документации для этого). В наше время это - стандартная программа кода, предоставленная библиотеками кода, и является наиболее часто используемым оболочками. Источник: Википедия.

Каталоги

Относительно почему ls -d файлы списков, а также каталоги...

ls страница справочника объясняет, почему это происходит, но с очень кратким объяснением. Таким образом, вот попытка расширенного объяснения:

По умолчанию ls перечисляет содержание каталогов при давании их имен и делании того же самого для символьных ссылок на каталоги. -d средства опции, "когда имя (имена) каталога (каталогов)" (которым можно также дать неявно globрезкий звук), только покажите _name_s каталога (каталогов), но не их содержание. Точно так же при обеспечении (явно или неявно) имя (имена) символьных ссылок на каталоги покажите имя файла символьной ссылки, не содержание каталога, на который это ссылается.

-d опции нечего делать, насколько я могу сказать, с которым перечислены объекты; это может быть сделано (источник: здесь) с find, как так: find . -maxdepth 1 -type d. Я не уверен, существует ли хороший способ сделать так только с GNU ls. Вот некоторые примеры того, как использовать find команда.

Таким образом подвести итог: По умолчанию ls показывает содержание каталогов при предоставлении их пути. -d изменения это поведение, только показывая само имя каталога, как был бы сделан для стандартного файла.

4
27.01.2020, 19:34

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

> {ice} ~ :10:47 % ls -l / 
total 97
drwxr-xr-x   2 root root  4096 May  3 00:27 bin
drwxr-xr-x   4 root root  1024 May  3 14:17 boot
drwxr-xr-x   2 root root  4096 Apr 29 13:44 cdrom
drwxr-xr-x  18 root root  4420 May  9 09:58 dev
...
lrwxrwxrwx   1 root root    33 May  3 14:16 vmlinuz -> boot/vmlinuz-3.9.0-030900-generic
lrwxrwxrwx   1 root root    29 May  3 11:07 vmlinuz.old -> boot/vmlinuz-3.8.0-19-generic
> {ice} ~ :10:47 % ls -ld /
drwxr-xr-x 25 root root 4096 May  3 14:16 /
3
27.01.2020, 19:34

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

Последовательность расширений слова для Bourne совместимая оболочка

  1. Расширение тильды
  2. Расширение параметра
  3. Замена команды
  4. Арифметическое расширение
  5. Полевое разделение
  6. Расширение пути
  7. Удаление кавычки

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

2
27.01.2020, 19:34

Ключевое слово Вам нужно (man bash) "Расширение Пути".

1
27.01.2020, 19:34
  • 1
    больше как "Расширение Пути" или "Поколение Имени файла". Связанный с "сопоставлением с образцом", но не тем же. –  Stéphane Chazelas 08.05.2013, 02:18
  • 2
    @StephaneChazelas Действительно, но "сопоставление с образцом" является подразделом "расширения пути" в странице справочника, тогда как "Поколение Имени файла" не происходит там вообще (только в информационном документе). Уверенный –  Hauke Laging 08.05.2013, 03:05

Теги

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