Por que encontrar uma impressão './' se nenhum caminho é dado?

13

Por que é que find imprime um resultado ./ aos resultados se nenhum caminho for dado?

$ find
./file1
./file2
./file3

Qual é o motivo para não imprimir isso?

$ find
file1
file2
file3
    
por n.r. 05.08.2016 / 18:55

4 respostas

17

A razão porque você vê isso é porque o desenvolvedor do GNU find escolheu para fornecer um comportamento "razoável" para > find quando nenhum caminho é dado. Em contraste, o POSIX não afirma que o parâmetro é opcional:

The find utility shall recursively descend the directory hierarchy from each file specified by path, evaluating a Boolean expression composed of the primaries described in the OPERANDS section for each file encountered. Each path operand shall be evaluated unaltered as it was provided, including all trailing <slash> characters; all pathnames for other files encountered in the hierarchy shall consist of the concatenation of the current path operand, a <slash> if the current path operand did not end in one, and the filename relative to the path operand. The relative portion shall contain no dot or dot-dot components, no trailing characters, and only single <slash> characters between pathname components.

Você pode ver a diferença na sinopse de cada um. O GNU possui (como é a convenção) itens opcionais em colchetes:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
       [expression]

enquanto o POSIX não indica que pode ser opcional:

find [-H|-L] path... [operand_expression...]

No programa GNU, isso é feito em ftsfind.c :

  if (empty)
    {
      /*
       * We use a temporary variable here because some actions modify
       * the path temporarily.  Hence if we use a string constant,
       * we get a coredump.  The best example of this is if we say
       * "find -printf %H" (note, not "find . -printf %H").
       */
      char defaultpath[2] = ".";
      return find (defaultpath);
    }

e um literal "." é usado para simplificar. Então você verá o mesmo resultado com

find

e

find .

porque (e POSIX concorda) o caminho será usado para prefixar os resultados (veja acima para concatenação ).

Com um pouco de trabalho, pode-se determinar quando o recurso foi adicionado pela primeira vez; estava 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 changelog do find 3.8, aparentemente foi

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 "."
    
por 05.08.2016 / 23:00
11

Normalmente, um faz o pós-processamento dos arquivos e, nesse caso, pode haver uma enorme vantagem em iniciar o nome do arquivo com ./ . Em particular, se um nome de arquivo começar com - , um comando subseqüente poderá interpretar esse nome de arquivo como uma opção. ./ evita isso.

Como exemplo, considere um diretório com esses arquivos:

$ ls
--link  --no-clobber

Agora, imagine como esse comando funcionaria se os nomes dos arquivos fossem fornecidos sem o ./ na frente:

$ find -type f -exec cp -t ../ {} +

Podemos ilustrar o problema com find . Vamos executá-lo no mesmo diretório acima. Os seguintes trabalhos:

$ find ./*
./--link
./--no-clobber

O seguinte falha:

$ find *
find: unknown predicate '--link'
Try 'find --help' for more information.
    
por 05.08.2016 / 19:06
5

O comando find precisa de caminho (s) para pesquisar. Se não especificarmos nenhum, ele usa o diretório atual ( . ) como ponto de partida. Da mesma forma, se você passar o caminho, por exemplo, /tmp , considera isso como ponto de partida. E, portanto, os resultados.

Se o diretório atual:

        $ find
or
        $ find .

output:
        ./file1
        ./file2
        ./file3

Se o diretório /tmp :

        $ find /tmp

output:
        /tmp/file4
        /tmp/file5

Se o diretório abc estiver no diretório atual:

        $ find abc

output:
        abc/file6
        abc/file7

Se houver vários diretórios no diretório atual:

        $ find fu bar

output:
        fu/file10
        fu/file11
        bar/file8
        bar/file9
    
por 05.08.2016 / 19:22
-2

Se você não especificar um caminho, o comando find assumirá o ${PWD} como o caminho e o imprimirá em sua saída. O usuário que não especificar o caminho não altera a maneira como find funciona. E encontrar sempre funciona com caminhos por padrão.

    
por 05.08.2016 / 19:01

Tags