Questão Como posso fazer o chown trabalhar de forma recursiva?


Eu tenho um diretório chamado pdfs que contém um grupo de subdiretórios e subdiretórios. Desejo alterar a propriedade em todos os arquivos PDF em todas as subpastas. Eu apenas tentei isso:

chown -R someuser:somegroup *.pdf

... mas não alterou a propriedade dos PDFs em subdiretórios. O usuário e o grupo existem.

Segundo a man page de chown, a -R deve significar recursivo:

-R, --recursive
          operate on files and directories recursively

o que estou perdendo?


226


origem




Respostas:


O modo recursivo funciona apenas em diretórios, não em arquivos. Usando o glob '* .pdf', o shell está passando a lista de arquivos para o chown, que vê esses arquivos, e altera as permissões nos arquivos que vê, e é isso.

Lembre-se, em shells, o glob é avaliado pelo shell, não pelo comando. Se o glob corresponder aos arquivos, eles serão passados ​​para o comando e o comando nunca saberá que um glob existiu. (Isso é diferente de como o prompt de comando do Windows costumava fazer as coisas). Se você tem um dir, com o conteúdo algo como:

machine:$ ls -F
file1.pdf  file2.pdf  other.txt  subdir/

E você digitou:

chown -R someuser:somegroup *.pdf

O shell primeiro faria a lista: file1.pdf file2.pdf

e, em seguida, execute seu comando:

chown -R someuser:somegroup file1.pdf file2.pdf

Veja, não há diretório para -R para agir. Ele faz o que você pediu - altere a propriedade dos dois arquivos na linha de comando, ignorando o peculiar sinalizador -R.

Para fazer o que você deseja, usar o '* .pdf' como um padrão para este diretório e subdiretórios, você pode usar find, que pode encontrar arquivos que correspondam a um padrão de nome de arquivo (ou muitos outros critérios) e passar para um subcomando

find . -type f -name '*.pdf' | xargs chown someuser:somegroup

Isso começa no diretório atual '.' procurar arquivos (filetype f) de padrão de nome '*.pdf' Em seguida, passa para xargs, que constrói uma linha de comando para chmod. Observe as aspas ao redor do padrão '*.pdf', lembre-se que o shell irá criar um glob se puder, mas você quer que o padrão seja passado para find, então você precisa citar.

Como nomes de arquivos podem ter espaços neles, você deseja usar um truque para tornar o nome do arquivo com espaços seguro:

find . -type f -name '*.pdf' -print0 | xargs -0 chown someuser:somegroup

No bash 3 e menor, esta é a maneira que você precisa fazer isso. Uma globbing mais poderosa está disponível na bash 4 (com shopt -s globstar) e outras conchas. O mesmo em zsh, usando um glob recursivo **:

chown -R someuser:somegroup ./**/*.pdf

232



Editado para refletir esse bash 4 com shopt -s globstar faz globalização recursiva. - kojiro
@kojiro obrigado! como você pode dizer eu ainda uso bash3 - Rich Homolka
De acordo com a página man mostrada pelo pôster original, eu encontrei o chown -R de fato mudei o dono em pastas E arquivos. Não há necessidade de encontrar. Usando Hortelã 15. - gwideman
@gwideman Eu sei que isso é antigo ... Mas sim, é claro -R faz recursivo. O OP só teve um problema com um tipo muito específico de recursão, uma extensão e um "tipo de arquivo é arquivo" filtrado - Rich Homolka
@RichHomolka Ah. OP disse que os arquivos estavam em um diretório chamado "pdfs", então eu assumi que o problema estava em como especificar pdfs como o diretório a ser recursivo, e que todos os arquivos contidos eram pdfs, então não há necessidade de selecioná-los especificamente. Mas você pode estar certo, se o trabalho for selecionar apenas arquivos pdf, e deixar outros inalterados. - gwideman


Não é complicado.

chown -R someuser:somegroup /your/folder/here/*

Isso aplicará chown a todos os arquivos e subdiretórios e subdiretórios da pasta especificada. Use com cuidado.


29



Claramente alguém responde desde 4 anos, mas ty para o aviso. - Francisco Tapia
Esta questão está atualmente em primeiro lugar no Google, por isso, é importante observar a resposta correta. - Sprachprofi
claro, o aceito é mais elegante, legível e completo - Francisco Tapia
De alguma forma sudo chown -R user ./ trabalhou para mim, mas sudo chown -R user ./* não fez - Slav
Eu sei que isso é antigo, mas embora isso responda ao título, não responde à pergunta. Isso é um pouco pior do que o que o OP já tentou. - Rich Homolka


Você pode usar o find utilidade:

find . -name '*.pdf' -exec chown someuser:somegroup {} +

Por favor, não esqueça as citações ao redor *.pdf. Caso contrário, o shell tentará expandi-lo. Isso significa que o shell irá substituir *.pdf com os nomes de todos os arquivos PDF encontrados no diretório atual. Mas não é isso que você quer. Você quer encontrar os arquivos PDF localizados em subdiretórios. Btw .: Esse também é o problema com o seu chown comando.


14



Eu tive que procurar o +, truque legal para o desempenho. -exec command {} + Essa variante da ação -exec executa o comando especificado nos arquivos selecionados, mas a linha de comando é criada anexando cada nome de arquivo selecionado no final; o número total de invocações do comando será muito menor que o número de arquivos correspondentes. A linha de comando é construída da mesma maneira que xargs constrói suas linhas de comando. Apenas um exemplo de {} é permitido dentro do comando. O comando é executado no diretório inicial. - Patrick M
@PatrickM uma (menor) outra vantagem para + vs; .... além disso, não é um metacaractere de shell e não precisa ser ignorado - Rich Homolka


O comando

chown -R someuser:somegroup *.pdf

só vai recorrer diretórios para baixo se o diretório nome termina em .pdf. Você precisa de algo como:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;

6



Tecnicamente, só irá para um nível abaixo. se você chama isso de recursão verdadeira ou não é um exercício para o usuário :) - Rich Homolka


para alterar a propriedade de um diretório de forma recursiva, basta usar:

sudo chown -R <username>:<groupname> <dir name>

aqui username = o novo usuário que deve ser o proprietário do diretório

groupname = o novo grupo que deve ser o proprietário do diretório

cada arquivo / diretório tem um proprietário de usuário e um proprietário de grupo


0



Isso não faz o que o OP pediu. Isso muda a propriedade de tudo, OP pediu por um conjunto específico de arquivos. - Rich Homolka


eu uso tree em vez de:

 sudo tree -fai ~/.blabla  | xargs -L1 -I{} sudo chown youruser:youruser {}

Também tome cuidado para não executar chown recursivo ou chmod no diretório '/' ou outro diretório do sistema.


0