Suas expectativas são baseadas no DOS Think / Windows Think e estão erradas. No MS-DOS, Windows e, na verdade, em alguns outros sistemas operacionais IBM / Microsoft, a expansão de curingas é feita pelo próprio comando, e coisas como a opção /a para o comando dir atuam como filtros de atributo durante a expansão de curingas. dir expande curingas como * , que o interpretador de comandos passa para ele como está e, se /a for especificado, aplica os filtros apropriados ao que é retornado. (Em alguns sistemas operacionais, os filtros de atributo podem ser fornecidos à chamada do sistema para enumerar um diretório e o kernel do sistema operacional, ou seus drivers de sistema de arquivos, os aplica por conta própria.)
No Unices e no Linux, a expansão de curingas é feita pelo shell e não reconhece as permissões. Quando, no diretório raiz, você faz
ls *
o que o comando ls em si recebe do shell é (algo como)
ls bin home opt var boot dev tmp etc lost+found root usr
O que a opção -d / --directory faz é desativar o que normalmente acontece a seguir . O que normalmente acontece a seguir é que ls olha cada um dos seus argumentos, vê que são diretórios e decide enumerar seu conteúdo. Para argumentos que nomeiam arquivos, ele apenas imprime as informações para o próprio arquivo. Com a opção -d , os diretórios são tratados como arquivos. Portanto, ls imprime as informações de cada um dos diretórios que são passados como seus argumentos, da mesma forma que faria se fossem arquivos.
Portanto, -d não é uma opção "somente diretórios de impressão". De fato, não existe apenas tal opção; lá não pode ser tal opção. A expansão de curingas é feita pelo shell e (em um POSIX sh pelo menos) não é possível dizer ao shell para verificar a permissão e os bits do tipo de arquivo quando ele expande * em uma lista de nomes. Para obter uma lista apenas dos nomes de diretórios, é necessário usar o comando find , conforme explicado por ztank1013 , ou usar o truque que um nome de caminho que termina com uma barra implica na entrada de diretório . , como explicado por Jin . (O truque de Jin termina com o comando ls recebendo os argumentos
ls bin/ home/ opt/ var/ boot/ dev/ tmp/ etc/ lost+found/ root/ usr/
porque o padrão */ está de fato combinando nomes de caminho com dois componentes, o segundo sendo vazio e, portanto, não está bastante fazendo o que foi desejado. Em particular, ele tratará links simbólicos apontando para diretórios como se fossem diretórios.)
O comportamento de ls -d sem * é uma simples extensão do acima. Basta saber mais uma coisa sobre ls : quando não é dado nenhum argumento, ele assume um argumento padrão de . . Agora sem a opção -d , o comportamento mencionado leva ao conteúdo do diretório nomeado por . sendo enumerado e as informações de seu conteúdo exibidas. Com a opção -d , o diretório . é tratado como se fosse um arquivo, e suas próprias informações são exibidas, ao invés de seu conteúdo ser enumerado.