Ваши ожидания основаны на 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опции каталог .обрабатывается так же, как если бы это был файл, и отображается его собственная информация, а не перечисленное содержимое.