- ao especificar
ls --directory a*
, deve listar apenas diretórios começando coma*
- MAS lista arquivos E diretórios começando com
a
Perguntas :
- onde posso encontrar alguma documentação sobre isso, além de
man
einfo
onde acho que olhei minuciosamente? - isso funciona apenas no BASH?
echo a*
também listará os arquivos que começam coma
(se houver). Apenas para deixar mais claro que não estáls
fazendo isso, mas sim o bash.Respostas:
A sintaxe
a*
e*a*
é implementada pelo shell, não pelols
comando.Quando você digita
no prompt do shell, o shell se expande
a*
para uma lista de todos os arquivos existentes no diretório atual cujos nomes começam coma
. Por exemplo, ele pode se expandira*
para a sequênciaa1 a2 a3
e passar esses argumentos parals
. Ols
comando em si nunca vê o*
personagem; ele só vê os três argumentosa1
,a2
ea3
.Para fins de expansão de curinga, "arquivos" refere-se a todas as entidades no diretório atual. Por exemplo,
a1
pode ser um arquivo normal,a2
um diretório ea3
um link simbólico. Todos eles têm entradas de diretório e a expansão de curinga do shell não se importa com o tipo de entidade a que essas entradas se referem.Praticamente todos os shells com os quais você provavelmente encontrará (bash, sh, ksh, zsh, csh, tcsh, ...) implementam curingas. Os detalhes podem variar, mas a sintaxe básica de
*
corresponder zero ou mais caracteres e?
qualquer caractere único é razoavelmente consistente.Para o bash, em particular, isso está documentado na seção "Expansão do nome do arquivo" do manual do bash; execute
info bash
e procure por "expansão de nome de arquivo" ou veja aqui .O fato de isso ser feito pelo shell, e não por comandos individuais, tem algumas conseqüências interessantes (e às vezes surpreendentes). A melhor coisa é que o manuseio de curinga é consistente para (quase) todos os comandos; se o shell não fizesse isso, inevitavelmente alguns comandos não se incomodariam e outros o fariam de maneiras sutilmente diferentes que o autor pensava serem "melhores". (Acho que o shell de comando do Windows tem esse problema, mas não estou familiarizado o suficiente para comentar mais.)
Por outro lado, é difícil escrever um comando para renomear vários arquivos. Se você escrever:
provavelmente falhará, pois
*.log.bak
é expandido com base nos arquivos que já existem no diretório atual. Existem comandos que fazem esse tipo de coisa, mas eles precisam usar sua própria sintaxe para especificar como os arquivos serão renomeados. Alguns comandos (comofind
) podem fazer sua própria expansão de curinga; você precisa citar os argumentos para suprimir a expansão do shell:A expansão do curinga do shell se baseia inteiramente na sintaxe do argumento da linha de comando e no conjunto de arquivos existentes. Não pode ser afetado pelo significado do comando. Por exemplo, se você deseja mover todos os
.log
arquivos para o diretório pai, pode digitar:Se você esquecer o
..
:e houver exatamente dois
.log
arquivos no diretório atual, ele será expandido para:que irá renomear
one.log
e derrotartwo.log
.EDIT : E depois de 52 votos positivos, um aceito e um distintivo de Guru, talvez eu deva realmente responder à pergunta no título.
A opção
-d
ou não indica para listar apenas diretórios. Ele diz para listar diretórios da mesma forma que eles, não seu conteúdo. Se você fornecer um nome de diretório como argumento , por padrão, ele listará o conteúdo do diretório, já que geralmente é disso que você está interessado. A opção diz para ele listar apenas o próprio diretório. Isso pode ser particularmente útil quando combinado com caracteres curinga. Se você digitar:--directory
ls
ls
-d
ls
fornecerá uma lista longa de cada arquivo cujo nome começa coma
e do conteúdo de cada diretório cujo nome começa coma
. Se você deseja apenas uma lista dos arquivos e diretórios, uma linha para cada, você pode usar:que é equivalente a:
Lembre-se novamente que o
ls
comando nunca vê o*
personagem.Quanto a onde isso está documentado,
man ls
mostrará a documentação para ols
comando em praticamente qualquer sistema semelhante ao Unix. Na maioria dos sistemas baseados em Linux, ols
comando faz parte do pacote GNU coreutils; se você possui oinfo
comando,info ls
ouinfo coreutils ls
deve fornecer uma documentação mais definitiva e abrangente. Outros sistemas, como o MacOS, podem usar versões diferentes dols
comando e podem não ter oinfo
comando; para esses sistemas, useman ls
. Els --help
mostrará uma mensagem de uso relativamente curta (117 linhas no meu sistema) se você estiver usando a implementação do coreUtil GNU.E sim, mesmo os especialistas precisam consultar a documentação de vez em quando. Veja também esta piada clássica .
fonte
a*
expande para uma lista de todos os arquivos no diretório atual cujos nomes começam coma
.ls subdir/a*
echo
ele. Então, se você quer saber o que está acontecendo quando você fazls a*
, primeiro executarecho ls a*
echo a*
... o shell faz expansão glob de qualquer maneirashopt -s failglob
faz com que o mesmo comportamento. Definir,nullglob
mas nãofailglob
faz, por exemplo,*nosuchfile*
expandir para uma sequência vazia.Veja a resposta de Keith Thompson; mas para explicar por que
ls --directory a*
arquivos espectáculos e diretórios: A--directory
opção não faz arquivos não-diretório reprimir. Em vez disso, lista os diretórios como tal, enquanto listaria seu conteúdo. Exemplo:fonte
-F
opçãoPara ser muito explícito, está documentado na página do manual ls (1) :
-d, --directory lista entradas de diretório em vez de conteúdo e não remove a referência de links simbólicos
para ser justo, "entradas em vez de conteúdo" provavelmente poderiam ser mais explicativas:
fonte
Globbing
Como foi explicado, a expansão de
*
(e expansões similares) é chamada deglob
bing no jargão do Unix e geralmente é um recurso do processador de comandos (conhecido como "shell" na linguagem do Unix). Portanto, o globbing também pode ser usado em muitos outros lugares; digiteman 7 glob
no shell de uma distribuição clássica do Linux (ou veja isso ) para obter mais informações sobre oglob
bing.No início do Unix,
glob
na verdade , era implementado por um programa separado chamado/etc/glob
(consulte a página 10 deste antigo manual do UNIX para obter a documentação). Atualmente, é uma rotina de código fornecida por bibliotecas de código e é comumente usada por shells. Fonte : Wikipedia .Diretórios
Por que
ls -d
lista arquivos e diretórios ...A
ls
página de manual explica por que isso acontece, mas com uma explicação muito concisa. Então, aqui está uma tentativa de uma explicação expandida:Por padrão,
ls
lista o conteúdo dos diretórios quando recebem seus nomes e fará o mesmo com links simbólicos para diretórios. A-d
opção significa "quando houver nomes de diretório (s)" (que também podem ser atribuídos implicitamente porglob
bing) , apenas mostre o _name_s do diretório (s), mas não seu conteúdo. Da mesma forma, quando fornecido com nomes explícitos ou implícitos de links simbólicos para diretórios , mostre o nome do arquivo do link simbólico, não o conteúdo do diretório ao qual ele faz referência.A
-d
opção não tem nada a ver, até onde sei, com quais itens estão listados; isso pode ser feito (fonte: aqui ) comfind
, assim:find . -maxdepth 1 -type d
. Não tenho certeza se existe uma boa maneira de fazer isso apenas com o GNUls
. Aqui estão alguns exemplos de como usar ofind
comandoPara resumir: Por padrão,
ls
mostra o conteúdo dos diretórios quando recebe o nome do caminho.-d
altera esse comportamento, mostrando apenas o próprio nome do diretório, como seria feito para um arquivo padrão.fonte
A documentação não diz que lista apenas as entradas de diretório, mas, quando
ls
recebe o nome do diretório, lista a entrada de diretório em vez de seu conteúdo. A melhor maneira de entender é por exemplo:fonte
A documentação faz parte do shell . Em particular, o shell executa várias expansões e substituições em uma ordem específica antes de executar um comando.
A sequência de expansões de palavras para um shell compatível com Bourne é
Portanto, o
ls
comando nem vê os*
caracteres, os argumentos já estão expandidos com todos os arquivos correspondentes aoa*
padrão glob. Isso é diferente do Windows, onde cada comando que precisa de globbing de nome de arquivo precisa implementar esse recurso.fonte
A palavra-chave que você precisa (
man bash
) é "Expansão do nome do caminho".fonte