Come posso fare in modo che l'abito funzioni in modo ricorsivo?


285

Ho una directory chiamata pdfsche contiene un sacco di sotto e sottodirectory. Voglio cambiare la proprietà su tutti i file PDF in tutte le sottocartelle. Ho appena provato questo:

chown -R someuser:somegroup *.pdf

... ma non ha cambiato la proprietà dei PDF nelle sottodirectory. L'utente e il gruppo esistono.

Secondo la pagina man di chown, -Rdovrebbe significare ricorsivo:

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

Cosa mi sto perdendo?

Risposte:


292

La modalità ricorsiva funziona solo su directory, non su file. Usando il glob '* .pdf' la shell sta passando l'elenco dei file a chown, che vede questi sono file e cambia le autorizzazioni sui file che vede, e basta.

Ricorda, nelle shell, il glob viene valutato dalla shell, non dal comando. Se il glob corrisponde ai file, vengono passati al comando e il comando non sa mai che esiste un glob. (Questo è diverso da come il prompt dei comandi di Windows usava fare le cose). Se hai un dir, con i contenuti qualcosa di simile a:

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

E hai digitato:

chown -R someuser:somegroup *.pdf

La shell dovrebbe prima fare la lista: file1.pdf file2.pdf

e quindi esegui il tuo comando:

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

Vedi, non esiste una directory per -R su cui agire. Fa quello che gli hai chiesto: cambia la proprietà dei due file sulla riga di comando, ignorando quel bizzarro flag -R.

Per fare quello che vuoi, usare '* .pdf' come modello per questa directory e sottodirectory, puoi usare find, che può trovare file che corrispondono a un modello di file (o molti altri criteri) e passare a un sottocomando

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

Questo inizia nella directory corrente '.' per cercare i file (tipo di file f) del modello del nome, '*.pdf'quindi passa a xargs, che costruisce una riga di comando in chmod. Nota le virgolette attorno al modello '*.pdf', ricorda che la shell creerà un glob se può, ma vuoi che il modello sia passato find, quindi devi citarlo.

Poiché i nomi dei file possono contenere spazi, devi usare un trucco per renderlo sicuro con nomefile:

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

In bash 3 e in basso, questo è il modo in cui devi farlo. Globbing più potente è disponibile in bash 4 (con shopt -s globstar) e altri gusci. Lo stesso in zsh, usando un glob ricorsivo **:

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

1
Modificato per riflettere che bash 4 con shopt -s globstarfa globbing ricorsivo.
Kojiro,

@kojiro grazie! come puoi dire, uso ancora bash3
Rich Homolka il

2
Per la pagina man mostrata dal poster originale, ho trovato che l'abito -R ha effettivamente cambiato proprietario su cartelle e file. Non c'è bisogno di trovare. Utilizzando Mint 15.
gwideman,

@gwideman So che questo è vecchio ... Ma sì, certo -R fa ricorsivo. L'OP ha appena avuto un problema con un tipo molto specifico di ricorsione, un'estensione e "il tipo di file è un file" filtrato uno
Rich Homolka

@RichHomolka Ah. OP ha detto che i file si trovavano in una directory chiamata 'pdfs', quindi ho ipotizzato che il problema fosse nel modo di specificare i pdf come directory da ricorrere e che tutti i file contenuti fossero pdf, quindi non è necessario selezionarli in modo specifico. Ma potresti avere ragione, se il lavoro è selezionare solo file PDF e lasciare invariati gli altri.
Gwideman,

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

Questo applicherà chown a tutti i file e tutte le sottodirectory e le sottodirectory della cartella specificata. Usare con cura.


2
In qualche modo ha sudo chown -R user ./funzionato per me, ma sudo chown -R user ./*non lo è
Slav

1
So che questo è vecchio, ma sebbene questo risponda al titolo, non risponde alla domanda. Questo in realtà è leggermente peggiore di quello che OP aveva già provato.
Rich Homolka,

2
@RichHomolka Essendo stato portato qui solo per il titolo della domanda, sono abbastanza felice di trovare questa risposta.
Félix Gagnon-Grenier,

@ FélixGagnon-Grenier abbastanza giusto. Se questa risposta funziona per te, sono molto felice. Ma non avrebbe funzionato per la domanda originale.
Rich Homolka,

Questo sembra non funzionare con file dot come .env.
Ryan,

14

È possibile utilizzare l' findutilità:

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

Per favore, non dimenticare le citazioni in giro *.pdf. Altrimenti la shell tenterà di espanderla. Questo significa che già la shell sostituirà *.pdfcon i nomi di tutti i file PDF trovati nella directory corrente. Ma non è quello che vuoi. Vuoi trovare i file PDF che si trovano nelle sottodirectory. Btw .: Questo è anche il problema con il tuo chowncomando.


1
Ho dovuto cercare il +trucco accurato per le prestazioni. -exec command {} +Questa variante dell'azione -exec esegue il comando specificato sui file selezionati, ma la riga di comando viene creata aggiungendo alla fine ciascun nome di file selezionato; il numero totale di invocazioni del comando sarà molto inferiore al numero di file corrispondenti. La riga di comando è costruita più o meno allo stesso modo che xargscrea le sue righe di comando. È {}consentita solo un'istanza di all'interno del comando. Il comando viene eseguito nella directory iniziale.
Patrick M,

@PatrickM un altro (minore) altro vantaggio rispetto a + vs; .... plus non è un meta personaggio shell e non deve essere evaso
Rich Homolka,

6

Il comando

chown -R someuser:somegroup *.pdf

ricercherà le directory solo se il nome della directory termina in .pdf. Hai bisogno di qualcosa come:

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

Tecnicamente passerà a un livello inferiore. che tu chiami quella vera ricorsione o no è un esercizio per l'utente :)
Rich Homolka

1

per modificare la proprietà di una directory in modo ricorsivo, utilizzare semplicemente:

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

qui username = il nuovo utente che dovrebbe essere il proprietario della directory

groupname = il nuovo gruppo che dovrebbe essere il proprietario della directory

ogni file / directory ha un proprietario utente e un proprietario di gruppo


Ciò non fa ciò che l'OP ha chiesto. Questo cambia la proprietà di tutto, OP ha richiesto un set specifico di file.
Rich Homolka,

0

Io uso treeinvece:

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

Inoltre, fare attenzione a non eseguire chown ricorsivi o chmod nella directory '/' o altra directory di sistema.


0

Per diventare il proprietario di tutti i file in una directory, utilizzare

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

invece di

sudo chown $USER directory\*

o

sudo chown --recursive $USER directory

che potrebbe non funzionare se ci sono troppi argomenti prodotti da * (troppi file nella directory) o che non fanno rispettivamente quello che vuoi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.