Como posso fazer o chown funcionar recursivamente?

234

Eu tenho um diretório chamado pdfs que contém vários subdiretórios e sub-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.

De acordo com a página man do chown , o -R deve significar recursivo:

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

O que estou perdendo?

    
por Nathan Long 22.03.2011 / 17:29

6 respostas

242

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 diretório, com o conteúdo parecido com:

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 '.' para procurar arquivos (filetype f) do padrão de nome '*.pdf' , em seguida, passa para xargs, que constrói uma linha de comando para chmod. Observe as aspas em torno do padrão '*.pdf' , lembre-se de que o shell criará um glob se puder, mas você deseja que o padrão seja passado para find , portanto, é necessário citá-lo.

Como nomes de arquivos podem ter espaços, você deve 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 inferior, é assim que você precisa fazer isso. Um globbing mais poderoso está disponível no bash 4 (com shopt -s globstar ) e outros shells. O mesmo em zsh, usando um globo recursivo ** :

chown -R someuser:somegroup ./**/*.pdf
    
por 22.03.2011 / 17:47
34

Não é complicado.

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.

    
por 09.11.2015 / 12:44
14

Você pode usar o utilitário find :

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

Por favor, não esqueça as citações em torno de *.pdf . Caso contrário, o shell tentará expandi-lo. Isso significa que o shell substituirá *.pdf pelos 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 comando chown .

    
por 22.03.2011 / 17:37
6

O comando

chown -R someuser:somegroup *.pdf

só irá redirecionar diretórios para baixo se o nome do diretório terminar em .pdf. Você precisa de algo como:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;
    
por 22.03.2011 / 17:38
0

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

todos os arquivos / diretórios têm um proprietário de usuário e um proprietário de grupo

    
por 11.05.2016 / 03:38
0

Eu uso tree :

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

Tenha também o cuidado de não executar o chown recursivo ou chmod no diretório '/' ou outro diretório do sistema.

    
por 25.01.2018 / 14:36