Wie kann ich Chown rekursiv arbeiten lassen?

285

Ich habe ein Verzeichnis mit dem Namen pdfs, das eine Reihe von Unter- und Unter-Unterverzeichnissen enthält. Ich möchte den Eigentümer für alle PDF-Dateien in allen Unterordnern ändern. Ich habe es gerade versucht:

chown -R someuser:somegroup *.pdf

... aber es hat den Besitz der PDFs in den Unterverzeichnissen nicht geändert. Der Benutzer und die Gruppe existieren.

Nach Angaben der Manpage chown, das -Rsollte bedeuten rekursiv:

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

Was vermisse ich?

Nathan Long
quelle

Antworten:

292

Der rekursive Modus funktioniert nur für Verzeichnisse, nicht für Dateien. Durch die Verwendung des Globus '* .pdf' übergibt die Shell die Dateiliste an chown, die erkennt, dass es sich um Dateien handelt, und ändert die Berechtigungen für die angezeigten Dateien.

Denken Sie daran, dass in Shells der Glob von der Shell und nicht vom Befehl ausgewertet wird. Wenn der Glob mit Dateien übereinstimmt, werden sie an den Befehl übergeben, und der Befehl weiß nie, dass ein Glob vorhanden ist. (Dies unterscheidet sich von der Windows-Eingabeaufforderung). Wenn Sie ein Verzeichnis haben, mit dem Inhalt etwas wie:

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

Und Sie tippten:

chown -R someuser:somegroup *.pdf

Die Shell würde zuerst die Liste erstellen: file1.pdf file2.pdf

und dann führe deinen Befehl aus:

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

Es gibt kein Verzeichnis, in dem -R aktiv sein könnte. Es macht, was Sie es gefragt haben - ändern Sie den Besitz für die beiden Dateien in der Befehlszeile und ignorieren Sie das skurrile -R-Flag.

Um das zu tun, was Sie möchten, können Sie das '* .pdf' als Muster für dieses Verzeichnis und die Unterverzeichnisse verwenden find, um Dateien zu finden, die einem Dateinamenmuster (oder vielen anderen Kriterien) entsprechen und an einen Unterbefehl übergeben werden

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

Dies beginnt in der aktuellen Richtung '.' Das Suchen nach Dateien (Dateityp f) mit dem Namen pattern wird '*.pdf'dann an xargs übergeben, das eine Befehlszeile für chmod erstellt. Beachten Sie die Anführungszeichen um das Muster. '*.pdf'Denken Sie daran, dass die Shell ein Glob erstellt, wenn dies möglich ist. Sie möchten jedoch, dass das Muster übergeben wird, findund müssen es daher in Anführungszeichen setzen.

Da Dateinamen Leerzeichen enthalten können, möchten Sie einen Trick anwenden, um Dateinamen mit Leerzeichen sicher zu machen:

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

In Bash 3 und niedriger ist dies die Art und Weise, wie Sie es tun müssen. Stärkeres Globbing ist in Bash 4 (mit shopt -s globstar) und anderen Shells verfügbar . Dasselbe in zsh mit einem rekursiven Glob **:

chown -R someuser:somegroup ./**/*.pdf
Reiche Homolka
quelle
1
Bearbeitet, um diese Bash 4 mit shopt -s globstarrekursivem Globbing widerzuspiegeln .
Kojiro
@kojiro danke! wie man sieht benutze ich noch bash3
Rich Homolka
2
Laut der Manpage, die auf dem Originalposter zu sehen ist, habe ich festgestellt, dass der Chown -R in der Tat den Besitzer für Ordner UND Dateien geändert hat. Keine Notwendigkeit zu finden. Using Mint 15.
gwideman
@gwideman Ich weiß, das ist alt ... Aber ja, natürlich - R ist rekursiv. Das OP hatte gerade ein Problem mit einer ganz bestimmten Art von Rekursion, einer Erweiterung und einer "Dateityp ist Datei" gefilterten
Rich Homolka
@RichHomolka Ah. OP sagte, die Dateien befänden sich in einem Verzeichnis mit dem Namen 'pdfs', und ich nahm an, dass das Problem darin bestand, pdfs als das zu rekursive Verzeichnis anzugeben, und dass alle enthaltenen Dateien pdfs waren, sodass sie nicht speziell ausgewählt werden mussten. Vielleicht haben Sie aber Recht, wenn Sie nur PDF-Dateien auswählen und andere unverändert lassen möchten.
Wideman
52
chown -R someuser:somegroup /your/folder/here/*

Dies gilt für alle Dateien und alle Unterverzeichnisse und Unterverzeichnisse des angegebenen Ordners. Mit Vorsicht verwenden.

Sprachprofi
quelle
2
Irgendwie sudo chown -R user ./hat es für mich funktioniert, aber sudo chown -R user ./*nicht
Slawischer
1
Ich weiß, dass dies alt ist, aber obwohl dies die Überschrift beantwortet, wird die Frage nicht beantwortet. Dies ist tatsächlich etwas schlimmer als das, was OP bereits versucht hatte.
Rich Homolka
2
@RichHomolka Nachdem ich nur wegen des Fragentitels hierher gebracht worden bin, freue ich mich sehr, diese Antwort zu finden.
Félix Gagnon-Grenier,
@FélixGagnon-Grenier fair genug. Wenn diese Antwort für Sie funktioniert, bin ich sehr glücklich. Aber bei der ursprünglichen Frage hätte es nicht geklappt.
Rich Homolka
Dies scheint nicht für Punktedateien wie z .env.
Ryan,
14

Sie können das findDienstprogramm verwenden:

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

Bitte vergessen Sie die Anführungszeichen nicht *.pdf. Andernfalls versucht die Shell, sie zu erweitern. Dies bedeutet, dass die Shell bereits durch *.pdfdie Namen aller PDF-Dateien im aktuellen Verzeichnis ersetzt wird. Aber das ist nicht was du willst. Sie möchten die PDF-Dateien in Unterverzeichnissen finden. Übrigens: Das ist auch das Problem mit Ihrem chownBefehl.

bmk
quelle
1
Ich musste den +netten Trick nachschlagen , um Leistung zu erzielen. -exec command {} +Diese Variante der Aktion -exec führt den angegebenen Befehl für die ausgewählten Dateien aus. Die Befehlszeile wird jedoch erstellt, indem jeder ausgewählte Dateiname am Ende angehängt wird. Die Gesamtzahl der Aufrufe des Befehls ist viel geringer als die Anzahl der übereinstimmenden Dateien. Die Befehlszeile ist in etwa so aufgebaut wie die xargsBefehlszeilen. {}Innerhalb des Befehls ist nur eine Instanz von zulässig. Der Befehl wird im Startverzeichnis ausgeführt.
Patrick M
@PatrickM ein (kleiner) weiterer Vorteil gegenüber + vs; .... plus ist kein Shell-Meta-Charakter und muss nicht entkommen
Rich Homolka
6

Der Befehl

chown -R someuser:somegroup *.pdf

Verzeichnisse werden nur dann wiederhergestellt, wenn der Verzeichnisname auf .pdf endet. Sie brauchen etwas wie:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;
Mike Scott
quelle
Technisch wird es nur eine Ebene tiefer gehen. ob Sie das echte Rekursion nennen oder nicht, ist eine Übung für den Benutzer :)
Rich Homolka
1

Um den Besitz eines Verzeichnisses rekursiv zu ändern, verwenden Sie einfach:

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

hier Benutzername = der neue Benutzer, der Eigentümer des Verzeichnisses sein soll

Gruppenname = Die neue Gruppe, die Eigentümer des Verzeichnisses sein soll

Jede Datei / jedes Verzeichnis hat einen Benutzer- und einen Gruppenbesitzer

KawaiKx
quelle
Dies entspricht nicht den Anforderungen des OP. Dadurch ändert sich die Eigentümerschaft von allem, und OP hat nach einem bestimmten Satz von Dateien gefragt.
Rich Homolka
0

Ich benutze treestattdessen:

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

Achten Sie auch darauf, dass Sie nicht rekursiv chown oder chmod im Verzeichnis '/' oder einem anderen Systemverzeichnis ausführen.

Eduard Florinescu
quelle
0

Verwenden Sie, um Eigentümer aller Dateien in einem Verzeichnis zu werden

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

Anstatt von

sudo chown $USER directory\*

oder

sudo chown --recursive $USER directory

Was möglicherweise nicht funktioniert, wenn zu viele Argumente von * (zu viele Dateien im Verzeichnis) erzeugt werden oder wenn nicht das getan wird, was Sie wollen.

masterxilo
quelle