Curing wildcards e arquivos de ponto

6

Eu sou um usuário de terminal iniciante tentando entender curingas. Acho que tenho uma boa noção disso, mas tenho algumas perguntas:

Por que os dois códigos a seguir funcionam conforme o esperado:

ls -d .[!.]?*
echo [D]*

Mas os 2 seguintes não:

ls -d [.][!.]?*
echo [D]

No primeiro comando, recebo um erro:

ls: cannot access [.][!.]*: No such file or directory

Quando estou tentando obter a mesma listagem ls -d .[!.]?* . E para o segundo, a saída é:

[D]

Quando estou esperando uma proclamação de erro ao longo das linhas de No such file or directory . o que estou perdendo? O que exatamente torna uma expressão um curinga, se esses elementos curinga mostrados no segundo conjunto de exemplos acima não forem cortados?

Esclarecimento (também em comentários):

O curinga [D]* não produz apenas D , mas também gera Desktop , Downloads etc. No entanto, eu também tentei echo [D] quando eu tinha um arquivo chamado D e quando eu não fez. A saída funcionou quando o arquivo D estava lá, mas também recebi a saída [D] quando não estava. Eu não entendi porque. Por que a presença do arquivo no diretório alterou a expressão [D] de um curinga para não?

    
por naxchange 02.04.2013 / 21:46

1 resposta

10

Por padrão, bash (o shell) não expande um nome de arquivo começando com um ponto (considerado um arquivo oculto) a menos que o ponto seja explicitamente especificado. Como [.] é um padrão, em vez de um caractere literal, ele não aciona a exibição de arquivos ocultos e, portanto, ls -d [.][!.]?* não corresponde a nada.

Você pode alterar esse comportamento padrão executando shopt -s dotglob , que define a opção para sempre incluir arquivos ocultos ao expandir os padrões de nome de arquivo (conhecidos como "globbing").

Exemplo (o cifrão no início da linha indica o prompt do shell; não digite-o):

$ touch .foo
$ ls -d .[!.]?*
.foo
$ ls -d [.][!.]?*
ls: cannot access [.][!.]?*: No such file or directory
$ shopt -s dotglob
$ ls -d [.][!.]?*
.foo

O problema com echo [D] é que a expansão não acontece se nenhum nome de arquivo for correspondido. Como você não tinha um arquivo chamado D quando tentou, echo foi dado e ecoou o que você digitou literalmente.

Um exemplo de expansão de nome de caminho que ocorre apenas quando um nome de arquivo corresponde a:

$ touch apple
$ echo a*
apple
$ rm apple
$ echo a*
a*

Se você excluir todos os arquivos que correspondem a [D]* , echo [D]* fornecerá [D]* .

    
por 03.04.2013 / 00:04