Não é um loop infinito , é apenas GNU find
reportando que echo
morreu de um SIGPIPE (porque a outra extremidade do canal no stdout foi fechada quando head
morreu) .
-execdir
não é especificado por POSIX. E mesmo para -exec
, não há nada em a especificação POSIX que diga que, se o comando for morto por um SIGPIPE, find
deve sair.
Então POSIX especificaria -execdir
, gfind
seria provavelmente mais compatível com POSIX do que seu BSD find
(supondo que seu BSD encontre saídas quando seu filho morrer de um SIGPIPE conforme a formulação da sua pergunta sugerir, FreeBSD find
não faz em meus testes e executa echo
em um loop para cada arquivo (como para o GNU find, não infinito)).
Você pode dizer que, para casos mais comuns, find
saindo de um filho morrendo de SIGPIPE seria preferível, mas o comando -exec
uted ainda poderia morrer de um SIGPIPE por outras razões que não o pipe em stdout sendo fechado, então sair find
para isso seria aceitável.
Com o GNU find
, você pode dizer ao find
para sair se um comando falhar com:
find . ... \( -exec echo {} \; -o -quit \)
Quanto a se uma implementação de find
é permitida ou proibida de relatar crianças morrendo de um sinal no stderr, aqui (com o uso de -execdir
) estamos fora do escopo do POSIX, mas se -exec
foi usado no lugar de -execdir
, parece que seria um caso em que gfind não está em conformidade.
A especificação para find
diz: "o erro padrão deve ser usado apenas para mensagens de diagnóstico" , mas também disponibiliza :
Default Behavior: When this section is listed as "The standard error shall be used only for diagnostic messages.", it means that, unless otherwise stated, the diagnostic messages shall be sent to the standard error only when the exit status indicates that an error occurred and the utility is used as described by this volume of POSIX.1-2008.
O que indicaria que, como find
não retorna com um status de saída diferente de zero nesse caso, ele não deve exibir essa mensagem no stderr.
Note que pelo texto, tanto o GNU quanto o FreeBSD find
não seriam compatíveis em um caso como:
$ find /dev/null -exec blah \;; echo "$?"
find: 'blah': No such file or directory
0
onde ambos relatam um erro sem definir o status de saída como diferente de zero. É por isso que eu levantei a questão sobre a lista de discussão do austin-group (os caras por trás do POSIX) .
Observe que, se você alterar seu comando para:
(trap '' PIPE; find -L /etc -execdir echo {} \; | head)
echo
ainda será executado para todos os arquivos, mas ainda falhará, mas, desta vez, echo
está relatando a mensagem de erro.
Agora, sobre filename
vs /etc/filename
vs ./filename
sendo exibido.
Novamente, a opção -execdir
não é padrão , não há texto que diga quem está certo e quem está errado. -execdir
foi introduzido pelo BSD find
e copiado posteriormente pelo GNU find
.
O GNU find
fez algumas mudanças (melhorias) intencionais sobre ele. Por exemplo, ele pré-anexa nomes de arquivos com ./
nos argumentos transmitidos aos comandos. Isso significa que find . -execdir cmd {} \;
não tem problemas com nomes de arquivos que começam com -
, por exemplo.
O fato de -L -execdir
não passar um caminho de arquivo relativo ao diretório pai é, na verdade, um bug que afeta a versão 4.3.0 a 4.5.8 do GNU find
. Foi corrigido em 4.5.9, mas isso está no ramo de desenvolvimento e não houve uma nova versão stable desde (a partir de 2015-12-22, embora um é iminente ).
Mais informações na lista de discussão findutils .
Se tudo o que você deseja é imprimir o nome base de todos os arquivos em /etc
portably, basta fazer:
find -L /etc -exec basename {} \;
Ou mais eficientemente:
find -L ///etc | awk -F / '/\/\// && NR>1 {print last}
{if (NF > 1) last = $NF
else last = last "\n" $NF}
END {if (NR) print last}'
que você pode simplificar para
find -L /etc | awk -F / '{print $NF}'
se você puder garantir que os caminhos de arquivo não contenham caracteres de nova linha (IIRC, algumas versões do OS / X possuem esses arquivos em / etc).
GNUly:
find -L /etc -printf '%f\n'
Sobre se:
find -exec echo {} \;
no link ao qual você está se referindo, é POSIX ou não.
Não, como uma chamada de comando, isso não é POSIX. Um script que teria que não seria compatível.
POSIX find
exige que pelo menos um caminho seja fornecido, mas deixa o comportamento não especificado se o primeiro argumento de não opção de find
começar com -
ou for um predicado find
(como !
, ou (
), portanto, o comportamento find
do GNU é compatível, portanto, implementações relatam um erro (ou tratam o primeiro argumento como um caminho de arquivo mesmo que ele represente um predicado de localização) ou spray red pintar na sua cara, não há nenhuma razão POSIXLY_CORRECT
afetaria o comportamento find
lá.