Por que é que find
imprime uma liderança ./
para resultados se nenhum caminho é dado?
$ find
./file1
./file2
./file3
Qual é o motivo para não imprimir isso?
$ find
file1
file2
file3
A razão pela qual você vê isso é porque o desenvolvedor do GNU escolheu fornecer um comportamento "razoável" para quando nenhum caminho for fornecido. Por outro lado, o POSIX não afirma que o parâmetro é opcional:find
find
O
find
utilitário deve descer recursivamente a hierarquia de diretórios de cada arquivo especificado pelo caminho , avaliando uma expressão booleana composta pelas primárias descritas na seção OPERANDS para cada arquivo encontrado. Cada operando de caminho deve ser avaliado inalterado conforme foi fornecido, incluindo todos os<slash>
caracteres finais ; todos os nomes de caminho para outros arquivos encontrados na hierarquia consistirão na concatenação do operando do caminho atual, a<slash>
se o operando do caminho atual não terminar em um e o nome do arquivo relativo ao operando do caminho. A parte relativa não deve conter componentes de ponto ou ponto, ponto à direitacaracteres e apenas<slash>
caracteres únicos entre os componentes do nome do caminho.
Você pode ver a diferença na sinopse para cada um. O GNU tem (como é a convenção) itens opcionais entre colchetes:
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
[expression]
enquanto POSIX não indica que pode ser opcional:
find [-H|-L] path... [operand_expression...]
No programa GNU, isso é feito em ftsfind.c
:
se (vazio) { / * * Usamos uma variável temporária aqui porque algumas ações modificam * o caminho temporariamente. Portanto, se usarmos uma constante de string, * temos um coredump. O melhor exemplo disso é se dissermos * "find -printf% H" (observe, não "find. -printf% H"). * / char defaultpath [2] = "."; return find (caminho padrão); }
e um literal "."
é usado para simplificar. Então você verá o mesmo resultado com
find
e
find .
porque (e POSIX concorda) o caminho fornecido será usado para prefixar os resultados (veja acima para concatenação ).
Com um pouco de trabalho, era possível determinar quando o recurso foi adicionado pela primeira vez; esteve presente na criação inicial de "findutils" em 1996 (ver find.c
):
+ /* If no paths are given, default to ".". */
+ for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
+ process_top_path (argv[i]);
+ if (i == 1)
+ process_top_path (".");
+
+ exit (exit_status);
+}
No registro de alterações da descoberta 3.8, isso foi aparentemente
Sat Dec 15 19:01:12 1990 David J. MacKenzie (djm at egypt)
* find.c (main), util.c (usage): Make directory args optional,
defaulting to "."
Geralmente, é feito o pós-processamento dos arquivos e, nesse caso, pode haver uma enorme vantagem em iniciar o nome do arquivo ./
. Em particular, se um nome de arquivo começar -
, um comando subseqüente poderá interpretar esse nome de arquivo como uma opção. ./
evita isso.
Como exemplo, considere um diretório com estes arquivos:
$ ls
--link --no-clobber
Agora, imagine como esse comando funcionaria se os nomes dos arquivos fossem fornecidos sem o nome ./
da frente:
$ find -type f -exec cp -t ../ {} +
Podemos ilustrar o problema consigo find
mesmo. Vamos executá-lo no mesmo diretório que acima. Os seguintes trabalhos:
$ find ./*
./--link
./--no-clobber
O seguinte falha:
$ find *
find: unknown predicate `--link'
Try 'find --help' for more information.
find *
.file
exigem que o usuário forneça um caminho (como o BSD encontra no OS X). Então, você geralmente precisa dizer algo parecidofind . -type f ...
. A partir daí, não é um grande passo para algumas versões do find (como o GNU find) simplesmente padronizar.
e deixar todo o resto como está.find *
não mostrar o.
é porque*
lista todos os arquivos e pastas, mas exclui.
. Façaecho *
em um diretório que contenha apenas um ou dois arquivos e você verá que.
não está listado. Assim,find *
opera em cada arquivo expandido. É o mesmo que se você dissessefind Desktop/
no diretório inicial. Você verá a saída comoDesktop/foo_bar.txt
find
se comporte dessa maneira. Você tem alguma informação de referência autorizada para apoiar a reivindicação implícita quefind
foi projetada para se comportar dessa maneira por esse motivo?O
find
comando precisa de caminhos para pesquisar. Se não especificarmos nenhum, ele usará o diretório atual (.
) como ponto de partida. Da mesma forma, se você passar o caminho, por exemplo/tmp
, ele considera isso como seu ponto de partida. E, portanto, os resultados.Se o diretório atual:
/tmp
Diretório If :abc
Diretório If no diretório atual:Se vários diretórios no diretório atual:
fonte
find
precisa de um caminho para pesquisar qualquer coisa e que o padrão seja o diretório atual. A questão é por que ele imprime o líder./
quandofile.txt
é exatamente o mesmo que./file.txt
.Se você não especificar um caminho, o
find
comando assumirá${PWD}
o caminho e o imprimirá em sua saída. O usuário que não especifica o caminho não muda a maneira comofind
funciona. E encontrar sempre funciona com caminhos por padrão.fonte
/tmp
, então não$PWD
é ./tmp
./
/tmp
, execute o comandofind /tmp
Se você não especificar um caminho que será sempre diretório atual, que é./
/tmp
. É que não pode ser$PWD
.${PWD}
foi o palavreado incorretafind .
,find $PWD
efind
(sem um caminho, se a sua descoberta o suportar).