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.