Diferentes comportamentos entre find -exec e piping through xargs [duplicate]

1
    

Esta pergunta já tem uma resposta aqui:

    

Eu queria recursivamente executar chmod go+w em uma pasta específica, incluindo arquivos ocultos, e tentei pela primeira vez

find . -name ".*" -o -name "*" -exec chmod go+w {} \;

mas descobri que não estava afetando arquivos ocultos. Para me verificar, eu corri apenas

find . -name ".*" -o -name "*"

e os arquivos ocultos foram listados. Eu também notei que se eu excluísse a parte -o -name "*" , chmod os arquivos ocultos (mas excluir os não ocultos, é claro). Minha última tentativa foi usar xargs em vez

find . -name ".*" -o -name "*" | xargs chmod go+w

que finalmente funcionou como esperado. O que estou fazendo errado no primeiro trecho?

Red Hat Enterprise Linux Server release 6.8 (Santiago)

GNU bash, version 4.3.42(1)-release (x86_64-unknown-linux-gnu)

    
por Brent 25.05.2017 / 00:25

1 resposta

4

A solução é ligar os dois testes de nomes com os parêntesis.

Para ilustrar isso, vamos considerar um diretório com três arquivos regulares:

$ ls -a
.  ..  .hidden1  .hidden2  not_hidden

Agora, vamos ao comando original:

$ find . -name ".*" -o -name "*" -exec echo Found {} \;
Found ./not_hidden

Apenas o arquivo não oculto é encontrado.

Em seguida, vamos adicionar parentes para agrupar os dois testes de nomes:

$ find . \( -name ".*" -o -name "*" \) -exec echo Found {} \;
Found .
Found ./not_hidden
Found ./.hidden1
Found ./.hidden2

Todos os arquivos são encontrados.

A solução é usar parênteses.

Mais detalhes

No comando original, não há operador entre -name "*" e -exec ... \; . Conseqüentemente, find assume o operador padrão que é lógico-e. Porque lógico-e liga-se mais apertado do que lógico-ou ( -o ), isso significa que o comando é interpretado como:

find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)

Isso significa que o exec é executado apenas se a primeira condição name não corresponder.

Para mais informações, consulte a seção OPERADORES em man find .

O que acontece sem -exec

Vamos tentar usar um simples -print :

$ find . -name ".*" -o -name "*" -print
./not_hidden

Como você pode ver, -print está vinculado ao -name "*" com o lógico implícito e como acima.

Mas, considere o que acontece sem qualquer ação especificada:

$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2

Aqui, todos os arquivos foram encontrados. A razão é que, nesta versão, -o é o operador somente .

    
por 25.05.2017 / 00:30