Ваши ожидания основаны на 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 etc lost+found root usr
Опция -d
/--directory
отключает то, что обычно происходит дальше. Далее обычно происходит следующее: ls
просматривает каждый из своих аргументов по очереди, видит, что они являются каталогами, и решает перечислить их содержимое. Для аргументов, которые называют файлы, он просто печатает информацию для самого файла. С опцией -d
каталоги обрабатываются как файлы. Поэтому ls
выводит информацию для каждого из каталогов, передаваемую в качестве аргументов, так же, как если бы они были файлами.
Так что -d
не является опцией "только для печати каталогов". На самом деле, не только нет такой возможности; не может быть такой возможности. Расширение с подстановочными знаками выполняется оболочкой, и (по крайней мере, в POSIX sh
) нет способа указать оболочке проверять биты прав доступа и типа файла, когда она расширяется *
в список имен. Чтобы получить список имен каталогов в одиночку, необходимо либо использовать команду find
, как объяснено в ztank1013
, либо использовать хитрость, заключающуюся в том, что путь, заканчивающийся косой чертой, подразумевает запись каталога .
как объяснил Jin
. (Уловка Jin
заканчивается тем, что команда ls
получает аргументы
ls bin/ home/ opt/ var/ boot/ dev/ tmp/ etc/ lost+found/ root/ usr/
потому что шаблон */
на самом деле совпадает с путевыми именами с двумя компонентами, второй является пустым, и поэтому не совсем делает то, что хотел. В частности, он будет обрабатывать символические ссылки, указывающие на каталоги, как если бы они были каталогами.)
Поведение ls -d
без *
является простым расширением вышеприведенного. Нужно просто знать еще одну вещь о ls
: когда ему не дано никаких аргументов, он принимает аргумент по умолчанию .
, Теперь без опции -d
вышеупомянутое поведение приводит к содержимому каталога с именем .
перечисляются и информация для его содержания отображается. С опцией -d
, каталог .
обрабатывается так же, как если бы это был файл, и отображается его собственная информация, а не перечисленное содержимое.