Como posso fazer o chown funcionar recursivamente?

285

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

chown -R someuser:somegroup *.pdf

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

De acordo com a página de manual de chown, o -Rdeve significar recursivo:

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

o que estou perdendo?

Nathan Long
fonte

Respostas:

292

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 chown, que vê esses arquivos, e altera as permissões nos arquivos que vê, e é isso.

Lembre-se, nas conchas, a glob é avaliada pelo shell, não pelo comando. Se o glob corresponder aos arquivos, eles são passados ​​para o comando e o comando nunca sabe que um glob existia. (É 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 faria primeiro a lista: file1.pdf file2.pdf

e execute o seu comando:

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

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

Para fazer o que você deseja, use o '* .pdf' como 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 (tipo de arquivo f) do padrão de nome '*.pdf'passa para xargs, que constrói uma linha de comando para chmod. Observe as aspas ao redor do padrão '*.pdf', lembre-se de que o shell criará um globo, se puder, mas você deseja que o padrão seja passado find, então você precisa citá-lo.

Como os nomes de arquivos podem ter espaços, você deve usar um truque para torná-lo seguro com nome de arquivo com espaços:

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

No bash 3 e inferior, é dessa maneira que você precisa fazer isso. Globbing mais poderoso está disponível no bash 4 (com shopt -s globstar) e em outros reservatórios. O mesmo no zsh, usando um globo recursivo **:

chown -R someuser:somegroup ./**/*.pdf
Rich Homolka
fonte
1
Editado para refletir que o bash 4 com shopt -s globstarfaz globbing recursivo.
Kojiro
@kojiro thanks! como você pode dizer que eu continuo a usar bash3
rico Homolka
2
De acordo com a página de manual mostrada no pôster original, descobri que o chown -R realmente mudou de proprietário nas pastas e arquivos. Não há necessidade de encontrar. Usando Mint 15.
gwideman 28/09
@gwideman Eu sei que isso é velho ... Mas sim, é claro que -R é recursivo. O OP só tinha um problema com um tipo muito específico de recursão, uma extensão e "tipo de arquivo é arquivo" filtrada um
rico Homolka
@RichHomolka Ah. A 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, portanto, 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.
precisa saber é o seguinte
52
chown -R someuser:somegroup /your/folder/here/*

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

Sprachprofi
fonte
2
De alguma forma, sudo chown -R user ./funcionou para mim, mas sudo chown -R user ./*não o fez
Slav
1
Sei que isso é antigo, mas, embora isso responda à manchete, não responde à pergunta. Na verdade, isso é um pouco pior do que o OP já havia tentado.
Rich Homolka
2
@RichHomolka Tendo sido trazido aqui apenas por causa do título da pergunta, estou muito feliz em encontrar esta resposta.
Félix Gagnon-Grenier
@ FélixGagnon-Grenier é bastante justa. Se esta resposta funcionar para você, estou muito feliz. Mas não teria funcionado para a pergunta original.
Rich Homolka 15/03
Isso parece não funcionar para arquivos de ponto como .env.
Ryan
14

Você pode usar o findutilitário:

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

Por favor, não esqueça as aspas *.pdf. Caso contrário, o shell tentará expandi-lo. Isso significa que o shell já será substituído *.pdfpelos nomes de todos os arquivos PDF encontrados no diretório atual. Mas não é isso que você quer. Você deseja encontrar os arquivos PDF localizados em subdiretórios. Btw .: Esse também é o problema do seu chowncomando.

bmk
fonte
1
Eu tive que procurar o +truque puro para o desempenho. -exec command {} +Essa variante da ação -exec executa o comando especificado nos arquivos selecionados, mas a linha de comandos é 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 xargscria suas linhas de comando. Apenas uma instância de {}é permitida dentro do comando. O comando é executado no diretório inicial.
Patrick M
@PatrickM uma (menor) outra vantagem de + vs; .... mais não é um personagem meta shell e não tem que ser escapado
rico Homolka
6

O comando

chown -R someuser:somegroup *.pdf

somente recursará os diretórios se o nome do diretório terminar em .pdf. Você precisa de algo como:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;
Mike Scott
fonte
Tecnicamente, ele irá apenas para um nível abaixo. se você chamar esse verdadeiro recursão ou não é um exercício para o usuário :)
rico Homolka
1

Para alterar a propriedade de um diretório recursivamente, basta usar:

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

aqui nome de usuário = 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

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

KawaiKx
fonte
Isso não faz o que o OP pediu. Isso muda a propriedade de tudo, o OP solicitou um conjunto específico de arquivos.
Rich Homolka
0

Eu uso em treevez disso:

 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 em outro diretório do sistema.

Eduard Florinescu
fonte
0

Para se tornar o proprietário de todos os arquivos em um diretório, use

find directory -type f -name '*' | sudo xargs -d '\n' chown $USER

ao invés de

sudo chown $USER directory\*

ou

sudo chown --recursive $USER directory

que pode não funcionar se houver muitos argumentos produzidos por * (muitos arquivos no diretório) ou que não faz o que você deseja, respectivamente.

masterxilo
fonte