Ваши ожидания основаны на DOS Think / Windows Think и ошибочны. В MS-DOS, Windows и некоторых других операционных системах IBM / Microsoft расширение по шаблону выполняется самой командой, а такие /a
параметры, как опция dir
команды, действуют как фильтры атрибутов при расширении по шаблону. dir
расширяет символы подстановки, например *
, которые интерпретатор команд передает ему как есть, и, если /a
указано, применяет соответствующие фильтры к возвращаемому. (В некоторых операционных системах фильтры атрибутов могут быть переданы системному вызову для перечисления каталога, и ядро операционной системы или драйверы его файловой системы применяют их самостоятельно.)
В Unices и в Linux расширение подстановочных знаков выполняется оболочкой и не учитывает разрешения. Когда в корневом каталоге вы делаете
ls *
что сама ls
команда получает от оболочки (что-то вроде)
ls bin home opt var boot dev tmp и т. д. lost + found root usr
Что -d
/ --directory
опция делает отключить то , что обычно происходит дальше . Что обычно происходит дальше, так это то ls
, что он по очереди просматривает каждый из его аргументов, видит, что они являются каталогами, и решает перечислить их содержимое. Для аргументов, которые называют файлы, он просто выводит информацию для самого файла. С этой -d
опцией каталоги обрабатываются как файлы. Поэтому ls
выводит информацию для каждого из каталогов, которая передается в качестве аргументов, так же, как если бы они были файлами.
Так что -d
это не опция «только для печати каталогов». На самом деле такой возможности нет; не может быть такой возможности. Расширение с подстановочными знаками выполняется оболочкой, и ( sh
по крайней мере, в POSIX ) нет способа указать оболочке проверять биты прав доступа и типов файлов при развертывании *
в список имен. Чтобы получить список только имен каталогов, необходимо либо использовать find
команду, как объяснено ztank1013
, либо использовать хитрость, заключающуюся в том, что имя пути, заканчивающееся косой чертой, подразумевает запись каталога .
, как объяснено Jin
. ( Jin
трюк заканчивается тем, что ls
команда получает аргументы
ls bin / home / opt / var / boot / dev / tmp / etc / lost + found / root / usr /
потому что шаблон */
на самом деле сопоставляет имена путей с двумя компонентами, причем второй является пустым, и поэтому не совсем делает то, что хотел. В частности, он будет обрабатывать символические ссылки, указывающие на каталоги, как если бы они были каталогами.)
Поведение ls -d
без *
является простым продолжением вышесказанного. Нужно просто знать еще одну вещь ls
: когда ему не дают аргументов, он принимает аргумент по умолчанию .
. Теперь без этой -d
опции вышеупомянутое поведение приводит к тому, что содержимое каталога, названного путем .
перечисления, и информация для его содержимого отображаются. С помощью этой -d
опции каталог .
обрабатывается так же, как если бы это был файл, и отображается его собственная информация, а не перечисленное содержимое.