題 如何遞歸地製作chown工作?


我有一個名為的目錄 pdfs 包含一堆子子目錄和子子目錄。我想更改所有子文件夾中所有PDF文件的所有權。我剛試過這個:

chown -R someuser:somegroup *.pdf

...但它沒有改變子目錄中PDF的所有權。用戶和組確實存在。

根據手冊頁 chown-R 應該是遞歸的:

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

我錯過了什麼?


234
2018-03-22 16:29


起源




答案:


遞歸模式僅適用於目錄,而不適用於文件。通過使用glob'* .pdf',shell將文件列表傳遞給chown,後者看到這些是文件,並更改了它看到的文件的權限,就是這樣。

請記住,在shell中,glob由shell評估,而不是命令。如果glob匹配文件,它們將被傳遞給命令,並且命令永遠不會知道glob存在。 (這與Windows命令提示符用於執行操作的方式不同)。如果你有一個目錄,內容如下:

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

你鍵入:

chown -R someuser:somegroup *.pdf

shell首先會列出清單: file1.pdf file2.pdf

然後運行您的命令:

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

看,沒有-R的目錄可以作用。它做你所要求的 - 改變命令行上兩個文件的所有權,忽略那個quirky -R標誌。

要做你想要的,使用'* .pdf'作為這個目錄和子目錄的模式,你可以使用 find,它可以找到與文件名模式(或許多其他criterea)匹配的文件並傳遞給子命令

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

這從當前目錄開始'。'查找名稱模式的文件(文件類型f) '*.pdf' 然後傳遞給xargs,它構造一個命令行到chmod。注意模式周圍的引號 '*.pdf',請記住,如果可以,shell將創建一個glob,但是你希望傳遞給它的模式 find,所以你需要引用它。

因為文件名中可能包含空格,所以您希望使用一種技巧使其文件名與空間安全:

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

在bash 3及更低版本中,這是您需要的方式。 bash 4中提供了更強大的globbing(帶有 shopt -s globstar)和其他砲彈。在zsh中使用遞歸glob相同 **

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

242
2018-03-22 16:47



編輯反映bash 4與 shopt -s globstar 做遞歸通配。 - kojiro
@kojiro謝謝!你可以告訴我仍然使用bash3 - Rich Homolka
根據原始海報顯示的手冊頁,我發現chown -R確實改變了文件夾AND文件的所有者。無需尋找。使用薄荷15。 - gwideman
@gwideman我知道這是舊的......但是,當然-R確實是遞歸的。 OP只是一個特定類型的遞歸問題,一個擴展名和“文件類型是文件”過濾了一個 - Rich Homolka
@RichHomolka啊。 OP說文件位於一個名為'pdfs'的目錄中,所以我認為問題在於如何指定pdfs作為遞歸目錄,並且所有包含的文件都是pdfs,因此不需要專門選擇它們。但你可能是對的,如果工作只選擇pdf文件,並保持其他人不變。 - gwideman


這並不復雜。

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

這將對所有文件以及指定文件夾的所有子目錄和子子目錄應用chown。小心使用。


33
2017-11-09 11:44



很明顯,有人在4年後回答了這個問題,但警告卻是ty。 - Francisco Tapia
這個問題目前在Google上排名第一,因此請務必注意正確的答案。 - Sprachprofi
當然,接受的更優雅,可讀和完整 - Francisco Tapia
不知何故 sudo chown -R user ./ 為我工作,但是 sudo chown -R user ./* 沒有 - Slav
我知道這已經過時了,但雖然這回答了標題,卻沒有回答這個問題。這實際上比OP已經嘗試的稍微差一些。 - Rich Homolka


你可以使用 find 效用:

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

請不要忘記周圍的報價 *.pdf。否則shell會嘗試擴展它。這意味著shell已經取代了 *.pdf 使用當前目錄中找到的所有PDF文件的名稱。但那不是你想要的。您想要找到位於子目錄中的PDF文件。順便說一句:這也是你的問題 chown 命令。


14
2018-03-22 16:37



我不得不抬頭看 +表演的巧妙技巧。 -exec command {} + -exec操作的此變體在所選文件上運行指定的命令,但命令行是通過在末尾附加每個選定的文件名來構建的;命令的調用總數將遠遠少於匹配文件的數量。命令行的構建方式與此非常相似 xargs 構建其命令行。只有一個實例 {} 在命令中是允許的。該命令在起始目錄中執行。 - Patrick M
@PatrickM一個(次要的)+ vs的其他優勢; .... plus不是shell元字符,不必轉義 - Rich Homolka


命令

chown -R someuser:somegroup *.pdf

如果是,只會遞歸目錄 目錄 名稱以.pdf結尾。你需要這樣的東西:

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

6
2018-03-22 16:38



從技術上講,它只會降低一級。你是否稱之為真正的遞歸是一個用戶的練習:) - Rich Homolka


以遞歸方式更改目錄的所有權只需使用:

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

這裡的用戶名=應該是目錄所有者的新用戶

groupname =應該是目錄所有者的新組

每個文件/目錄都有一個用戶所有者和一個組所有者


0
2018-05-11 01:38



這不符合OP的要求。這改變了一切的所有權,OP要求提供一組特定的文件。 - Rich Homolka


我用 tree 代替:

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

另外注意不要在'/'目錄或其他系統目錄上運行recursive chown或chmod。


0
2018-01-25 13:36