Bagaimana saya bisa membuat chown bekerja secara rekursif?

285

Saya punya direktori bernama pdfsyang berisi banyak sub-dan-sub-direktori. Saya ingin mengubah kepemilikan pada semua file PDF di semua subfolder. Saya baru saja mencoba ini:

chown -R someuser:somegroup *.pdf

... tetapi itu tidak mengubah kepemilikan PDF di subdirektori. Pengguna dan grup memang ada.

Menurut halaman manual untuk chown, yang -Rseharusnya berarti rekursif:

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

Apa yang saya lewatkan?

Nathan Long
sumber

Jawaban:

292

Mode rekursif hanya berfungsi pada direktori, bukan file. Dengan menggunakan glob '* .pdf', shell mengirimkan daftar file ke chown, yang melihat ini adalah file, dan mengubah izin pada file yang dilihatnya, dan hanya itu.

Ingat, di shell, glob dievaluasi oleh shell, bukan perintah. Jika glob cocok dengan file, mereka diteruskan ke perintah dan perintah tidak pernah tahu ada glob. (Ini berbeda dari bagaimana Windows Command prompt digunakan untuk melakukan sesuatu). Jika Anda memiliki dir, dengan isinya sesuatu seperti:

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

Dan Anda mengetik:

chown -R someuser:somegroup *.pdf

Shell pertama-tama akan membuat daftar: file1.pdf file2.pdf

dan kemudian jalankan perintah Anda:

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

Lihat, tidak ada direktori untuk -R untuk ditindaklanjuti. Itu melakukan apa yang Anda tanyakan - mengubah kepemilikan pada dua file pada baris perintah, mengabaikan bendera -R yang unik.

Untuk melakukan apa yang Anda inginkan, untuk menggunakan '* .pdf' sebagai pola untuk direktori dan subdirektori ini, Anda dapat menggunakan find, yang dapat menemukan file yang cocok dengan pola nama file (atau banyak kriteria lain) dan meneruskan ke subperintah.

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

Ini dimulai dengan dir saat ini '.' untuk mencari file (tipe file f) dari pola nama '*.pdf'kemudian beralih ke xargs, yang membangun sebuah baris perintah ke chmod. Perhatikan tanda kutip di sekitar pola '*.pdf', ingat bahwa shell akan membuat gumpalan jika bisa, tetapi Anda ingin pola itu diteruskan find, jadi Anda perlu mengutipnya.

Karena nama file mungkin memiliki spasi di dalamnya, Anda ingin menggunakan trik untuk menjadikannya nama file-dengan-spasi:

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

Dalam bash 3 dan lebih rendah, ini adalah cara yang perlu Anda lakukan. Globbing yang lebih kuat tersedia di bash 4 (dengan shopt -s globstar) dan cangkang lainnya. Hal yang sama di zsh, menggunakan bola rekursif **:

chown -R someuser:somegroup ./**/*.pdf
Homolka yang kaya
sumber
1
Diedit untuk mencerminkan bash 4 dengan shopt -s globstarglobbing rekursif.
kojiro
@ Kojiro terima kasih! seperti yang Anda tahu saya masih menggunakan bash3
Rich Homolka
2
Per halaman manual yang ditunjukkan oleh poster asli, saya menemukan chown -R memang mengubah pemilik pada folder DAN file. Tidak perlu ditemukan. Menggunakan Mint 15.
gwideman
@ gwideman Saya tahu ini sudah tua ... Tapi ya, tentu saja -R tidak rekursif. OP baru saja mengalami masalah dengan jenis rekursi yang sangat spesifik, ekstensi dan "jenis file adalah file" yang difilter
Rich Homolka
@RichHomolka Ah. OP mengatakan file-file itu berada di direktori yang disebut 'pdf', jadi saya berasumsi masalahnya adalah bagaimana menentukan pdf sebagai direktori yang akan diulang, dan semua file yang ada adalah pdf, jadi tidak perlu memilihnya secara khusus. Tapi Anda mungkin benar, jika tugasnya hanya memilih file pdf, dan membiarkan orang lain tidak berubah.
gwideman
52
chown -R someuser:somegroup /your/folder/here/*

Ini akan berlaku untuk semua file dan semua subdirektori dan subdirektori dari folder yang ditentukan. Gunakan dengan hati-hati.

Sprachprofi
sumber
2
Entah bagaimana sudo chown -R user ./bekerja untuk saya, tetapi sudo chown -R user ./*tidak
Slav
1
Saya tahu ini sudah tua, tetapi meskipun ini menjawab judul, tidak menjawab pertanyaan. Ini sebenarnya sedikit lebih buruk daripada yang telah dicoba OP.
Rich Homolka
2
@RichHomolka Telah dibawa ke sini hanya karena judul pertanyaan, saya cukup senang menemukan jawaban ini.
Félix Gagnon-Grenier
@ FélixGagnon-Grenier cukup adil. Jika jawaban ini cocok untuk Anda, saya sangat senang. Tapi itu tidak akan berhasil untuk pertanyaan aslinya.
Rich Homolka
Ini sepertinya tidak berfungsi untuk file dot seperti .env.
Ryan
14

Anda dapat menggunakan findutilitas:

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

Tolong jangan lupa tanda kutip di sekitar *.pdf. Kalau tidak, shell akan mencoba mengembangkannya. Ini berarti shell akan diganti *.pdfdengan nama-nama semua file PDF yang ditemukan di direktori saat ini. Tapi bukan itu yang Anda inginkan. Anda ingin mencari file PDF yang terletak di subdirektori. Btw .: Itu juga masalah dengan chownperintah Anda .

bmk
sumber
1
Saya harus melihat +, trik untuk kinerja. -exec command {} +Varian aksi -exec ini menjalankan perintah yang ditentukan pada file yang dipilih, tetapi baris perintah dibangun dengan menambahkan setiap nama file yang dipilih di akhir; jumlah total doa perintah akan jauh lebih sedikit daripada jumlah file yang cocok. Baris perintah dibangun dengan cara yang sama dengan yang xargsmembangun baris perintahnya. Hanya satu instance dari {}yang diizinkan dalam perintah. Perintah dijalankan di direktori awal.
Patrick M
@PatrickM satu (minor) keuntungan lain dari + vs; .... plus bukan karakter meta shell dan tidak harus melarikan diri
Rich Homolka
6

Perintah

chown -R someuser:somegroup *.pdf

hanya akan mengulang direktori jika nama direktori berakhir dengan .pdf. Anda membutuhkan sesuatu seperti:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;
Mike Scott
sumber
Secara teknis itu hanya akan turun satu tingkat. apakah Anda menyebut rekursi sejati atau tidak adalah latihan untuk pengguna :)
Rich Homolka
1

untuk mengubah kepemilikan direktori secara rekursif cukup gunakan:

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

di sini username = pengguna baru yang harus menjadi pemilik direktori

groupname = grup baru yang harus menjadi pemilik direktori

setiap file / direktori memiliki pemilik pengguna dan pemilik grup

KawaiKx
sumber
Ini tidak melakukan apa yang diminta OP. Ini mengubah kepemilikan segalanya, OP meminta set file tertentu.
Rich Homolka
0

Saya menggunakan treesebagai gantinya:

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

Juga berhati-hatilah untuk tidak menjalankan chown atau chmod rekursif pada direktori '/' atau direktori sistem lainnya.

Eduard Florinescu
sumber
0

Untuk menjadi pemilik semua file dalam direktori, gunakan

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

dari pada

sudo chown $USER directory\*

atau

sudo chown --recursive $USER directory

yang mungkin tidak berfungsi jika ada terlalu banyak argumen yang dihasilkan oleh * (terlalu banyak file dalam direktori) atau yang tidak masing-masing melakukan apa yang Anda inginkan.

masterxilo
sumber