find. [^.] * -type f -print0 | xargs -0 sudo chmod 664; não funciona

3

Estou usando este comando para definir permissões para arquivos recursivamente

clime@vm6879 /srv/www-php/steeltrading $ find . .[^.]* -type f -print0 | xargs -0 sudo chmod 664

Mas depois de executar esse comando, as permissões de alguns arquivos (a maioria delas) ainda não foram alteradas.

clime@vm6879 /srv/www-php/steeltrading $ ll media/xmlconnect/system/ok.gif 
-rwxrwxr-x. 1 www www 295 Jul  5  2012 media/xmlconnect/system/ok.gif

Se eu executar apenas find para ver se o arquivo está na lista, posso vê-lo:

clime@vm6879 /srv/www-php/steeltrading $ find . .[^.]* -type f | grep ok.gif
./media/xmlconnect/custom/ok.gif
./media/xmlconnect/original/ok.gif
./media/xmlconnect/system/ok.gif

Se eu mudar para a mídia de diretório e executar o comando novamente, o arquivo finalmente obterá as permissões corretas.

clime@vm6879 /srv/www-php/steeltrading $ cd media/
clime@vm6879 /srv/www-php/steeltrading/media $ find . .[^.]* -type f -print0 | xargs -0 sudo chmod 664
clime@vm6879 /srv/www-php/steeltrading/media $ ll xmlconnect/system/ok.gif 
-rw-rw-r--. 1 www www 295 Jul  5  2012 xmlconnect/system/ok.gif

Parece que sudo chmod 664 não é executado para alguns arquivos e parece que xargs é o problema, mas é estranho (sem mensagens de erro). Alguma ideia do que pode ser a causa, por favor?

EDIT: Ou talvez muitos dados podem ser um problema?

    
por clime 17.04.2013 / 14:40

3 respostas

6

find não irá ignorar os arquivos de pontos, portanto .[^.]* ( .[!.]* na sintaxe padrão) é redundante e fará com que esses arquivos sejam processados duas vezes (e os diretórios sejam descendentes duas vezes). (observe também que .[!.]* não possui arquivos chamados ..foo , por exemplo).

No entanto, find , por padrão, não desce em links simbólicos para diretórios. Então, se media é um link simbólico para uma área fora de . , os arquivos lá não serão processados.

Você pode usar -L para dizer ao find para seguir os links simbólicos. Observe, no entanto, que isso também fará com que chmod seja chamado para arquivos que sejam links simbólicos para arquivos regulares.

sudo find -L . -type f -exec chmod 664 {} +

Ou com algumas implementações find / xargs :

find -L . -type f -print0 | sudo xargs -r0 chmod 664

Ao contrário do que foi dito aqui, xargs e find -exec + resolverão dividir a lista de argumentos em chmod se for muito grande.

No entanto, deve-se notar que o limite que estamos falando aqui é o tamanho cumulativo dos argumentos e do ambiente passado para um comando (para a chamada de sistema execve(2) ).

find e xargs garantirão que esse limite não seja atingido (e deixará uma pequena margem), mas se você executá-lo como:

find . -type f -print0 | xargs -r0 sudo chmod 644

em vez de:

find . -type f -print0 | sudo xargs -r0 chmod 644

O comando sudo (chamado por xargs ) receberá todos os argumentos para passar para chmod e também passará uma variável de ambiente SUDO_COMMAND para chmod que contém a lista de arquivos outra vez, então será aproximadamente o dobro do tamanho de arg + env passado para chmod e explicará porque o limite foi excedido.

    
por 18.04.2013 / 00:18
1

É possível que a string de argumento que você está passando para chmod seja muito longa. Você tem algumas opções aqui.

Usando a opção exec do find

Quando usado com um ponto-e-vírgula, a opção exec do find executará um comando uma vez por arquivo que encontrar: find . .[^.]* -type f -exec sudo chmod 664 -- '{}' \; .

Limitando o número de argumentos com xargs

xargs -n5 passará no máximo cinco argumentos por instância de comando. Você também pode usar o sinalizador -s para limitar o número de caracteres passados ao comando: xargs -s4096 . Você pode aumentar os limites para um melhor desempenho; apenas tenha cuidado para não ir para o alto.

Chmod recursivo

chmod tem uma opção recursiva. Isso afetará diretórios e arquivos. Se você está preocupado com a desabilitação dos bits de execução nos diretórios, você pode executar chmod -R +X (observe a letra maiúscula X ) depois de executar seu primeiro comando para definir recursivamente os bits de execução de seus diretórios.

    
por 17.04.2013 / 15:07
-1

Eu não vejo o que você está tentando fazer com o nome do diretório. [^.] * (Eu acho que é redundante) e eu não acho que você precisa -print0 -0 opções, eu suspeito que você está recebendo um buffer overflow em algum lugar ou tamanho da linha de comando

tente

find . -f file  -xargs chmod {}\;

Você poderia usar -v no chmod para ver o arquivo ech sendo alterado.

    
por 17.04.2013 / 15:24