find: significado do \? assine como um valor do parâmetro name

1

Qual é o significado do? assina o seguinte comando?

find /foo/path -name \?
    
por DreamWalker 25.05.2016 / 10:36

2 respostas

2

O ? faz parte de um mecanismo chamado "expansão do nome do caminho" no shell .

Coloquialmente, o mecanismo de shell é chamado de "globing". O glob básico usa apenas três caracteres: * ? e [ que criam "padrões".

Um asterisco * significa:

  • Qualquer caractere em qualquer quantidade (qualquer string).

Um ponto de interrogação ( ? ) significa:

  • Qualquer caractere uma vez .

As chaves quadradas definem uma lista de caracteres [ ] e significam:

  • Apenas os caracteres dentro da lista são contados uma vez. Pode haver listas negadas.

Esses caracteres são usados de maneira semelhante no comando find . Em encontrar, eles são chamados de "padrões".

Isso significa que existem duas entidades usando os mesmos caracteres para executar a mesma tarefa (globing). É preciso dizer a alguém para ignorar esses personagens. A maneira usual de dizer ao shell para evitar a interpretação de caracteres especiais é "citá-los". Com "aspas simples", "aspas duplas" ou com uma barra invertida:

'?'
"?"
\?

É por isso que os "padrões" para find são citados:

find /path/foo -name \?

O que essa linha significa é:

Listar todos os arquivos e diretórios a partir do diretório /path/foo que tem um nome com apenas um caractere de largura.

sobre /

Observe isso? na expansão de padrão do find pode corresponder a / .

Um pattern em encontrar pode corresponder a / conforme especificado pelo POSIX dentro dos operandos seção para o comando find :

-path pattern The primary shall evaluate as true if the current pathname matches pattern using the pattern matching notation described in Pattern Matching Notation. The additional rules in Patterns Used for Filename Expansion do not apply as this is a matching operation, not an expansion.

Novamente: regras adicionais ... para Expansão de nome de arquivo (como em um shell) não se aplicam, pois essa é uma operação de correspondência, não uma expansão.

Para mostrar que isso é verdade:

$ mkdir test; cd test
$ mkdir -p a/b/c/d
$ find a -path 'a?b'
a/b
$ find . -path './a?b?c?d'
./a/b/c/d

É claro que a opção -name de find corresponderá ao basename de um arquivo. Isso, por definição, não poderia ter um / , pois não é possível corresponder um / em um nome de base.

    
por 25.05.2016 / 11:30
3

? é um caractere especial na correspondência de padrões , que corresponde a qualquer personagem.

Portanto, o comando significa localizar todos os arquivos e diretórios em /foo/path e seus subdiretórios, cujos nomes têm exatamente um caractere.

O \? é usado para impedir que o seu shell execute a geração de nome de arquivo . Você pode usar outros mecanismos de cotação :

find /foo/path -name '?'

ou:

find /foo/path -name "?"

Observe que ? nos padrões de expansão de nome de arquivo nunca correspondem a / , e também que o padrão dado a -name , por causa da barra, será ignorado ao computar o nome-base () do arquivo (A basename é a final, ou apenas , nome do arquivo em um nome de caminho e um nome_do_arquivo , no contexto do nome do caminho, pode ser seguido por barras à direita):

$ mkdir a b
$ find a/ b/ -name a -o -name b\?
a/

produz apenas a/ .

A única exceção é / e // em implementações em que // não se refere a / :

$ find / ! -path / -prune -o -name \? -print
/

( A definição POSIX é um pouco incerta sobre o nome de base de / , // e ///+ )

ou no busybox encontrar:

$ busybox find a/ b/ -name a -o -name b\?
b/

Se você tentar usar / no padrão dado a -name , o comportamento varia dependendo da implementação.

O BSD find e o heirloom find tratam a expressão como falsa, não produzem nada:

$ find /tmp -name /tmp
$ echo "$?"
0

O GNU find fornece a mensagem de aviso:

$ find /tmp -name /tmp
find: warning: Unix filenames usually don't contain slashes (though pathnames do).
That means that '-name ‘/tmp’' will probably evaluate to false
all the time on this system. You might find the '-wholename' test more useful,
or perhaps '-samefile'. Alternatively, if you are using GNU grep,
you could use 'find ... -print0 | grep -FzZ ‘/tmp’'.

E o código de retorno é 0.

    
por 25.05.2016 / 10:48