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.