題 如何遞歸chmod除文件以外的所有目錄?


如何chmod 755所有目錄但沒有文件(遞歸)?

反過來,如何chmod只有文件(遞歸)但沒有目錄?


528
2018-01-06 01:56


起源


有關: 將目錄的所有文件和文件夾權限更改為644/755 在SO - kenorb
有關: 使用一個命令更改所有文件夾權限 在U&L。 - Scott


答案:


以遞歸方式給予 目錄 讀取和執行權限:

find /path/to/base/dir -type d -exec chmod 755 {} +

以遞歸方式給予  讀權限:

find /path/to/base/dir -type f -exec chmod 644 {} +

或者,如果要處理的對像很多:

chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)

或者,減少 chmod 產卵:

find /path/to/base/dir -type d -print0 | xargs -0 chmod 755 
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644

736
2018-01-06 01:58



對於包含太多文件的目錄,前兩個示例失敗: -bash: /bin/chmod: Argument list too long。最後一個命令適用於許多文件,但在使用時 sudo 一個人必須小心把它放在xargs而不是chmod之前: find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755 - Agargara
還要注意,這些命令是 包括的 基地的目錄。所以在上面的例子中, dir 也將設置為755。 - CenterOrbit
chmod ... $(find /path/to/base/dir -type ...) 對於名稱中包含空格的文件名失敗。 - Dan Dascalescu
我認為關於文件名和文件數中的空格和符號的最正確(但不是最快)版本是 find /path/to/base/dir -type d -exec chmod 755 {} \; (find /path/to/base/dir -type f -exec chmod 644 {} \;)。 - Peter K


這類事情的一個常見原因是將目錄設置為755但文件設置為644.在這種情況下,有一種比nik更快的方式 find 例:

chmod -R u+rwX,go+rX,go-w /path

含義:

  • -R =遞歸;
  • u+rwX =用戶可以讀,寫和執行;
  • go+rX =組和其他人可以閱讀和執行;
  • go-w =小組和其他人不能寫

這裡要注意的重要一點是大寫 X 對小寫的行為不同 x。在手冊中我們可以閱讀:

如果文件是目錄或任何執行/搜索位在原始(未修改)模式中設置,則執行/搜索位。

換句話說,文件上的chmod u + X不會設置執行位;並且只有在已經為用戶設置的情況下,g + X才會設置它。


265
2018-01-06 03:22



-R =遞歸; u + rwX =用戶可以讀,寫和執行; go + rX = group,其他人可以讀取和執行; go-w = group和其他人不能寫 - släcker
當某人完成時,這種模式不會解決這種情況 chmod -R 777 自從 +X 選項不會重置文件上的現有執行位。使用-x將重置目錄,並防止降級到它們。 - Andrew Vit
@ ring0:我不打算按字面意思回答這個問題 - nik已經做得非常好了。我指出了最常見案例的更便宜的解決方案。是的,你確實獲得了不同的文件和目錄權限 X,如評論中所述。 - bobince
go+rX,go-w  - > go=rX 不是嗎? - Pierre de LESPINAY
你也可以使用 chmod u-x,u+X 組合等,刪除文件的執行位,但為目錄添加它們。 - w0rp


如果要確保文件設置為644並且路徑中有文件具有執行標誌,則必須先刪除執行標誌。 + X不會從已經擁有它的文件中刪除執行標誌。

例:

chmod -R ugo-x,u+rwX,go+rX,go-w path

更新:這似乎失敗,因為第一次更改(ugo-x)使目錄無法執行,因此其下的所有文件都不會更改。


12
2018-01-22 16:14



這對我有用,我不明白為什麼它不會。 (當然,如果你這樣做的話 chmod -R ugo-x path,這可能是個問題。但完整的命令將完成 chmod u+rwX 在每個目錄嘗試下降之前。)但是,我相信 chmod R u=rw,go=r,a+X path 足夠 - 而且它更短。 - Scott
我發現這個工作正常;輸入目錄沒有問題 - Someone Somewhere


我決定自己寫一個小腳本。

dirs和/或文件的遞歸chmod腳本 - Gist

它基本上執行遞歸chmod,但也為命令行選項提供了一些靈活性(設置目錄和/或文件權限,或排除它自動將所有內容重置為755-644)。它還會檢查一些錯誤情況。

我也寫過它 在我的博客上


4
2017-09-18 14:00





以遞歸方式給予 目錄 讀取和執行權限:

find /path/to/base/dir -type d -exec chmod 755 {} \;

以遞歸方式給予  讀權限:

find /path/to/base/dir -type f -exec chmod 644 {} \;

遲到總比沒有讓我在正確性方面升級nik的答案。我的解決方案速度較慢,但它適用於任意數量的文件,文件名中包含任何符號,並且您可以正常使用sudo運行它(但要注意它可能會發現帶有sudo的不同文件)。


2
2018-02-21 11:58



這是一個 下坡 的 尼克的回答。為什麼你認為nik的答案有什麼問題? - Scott
@Scott,nik的回答失敗了(vey)大量文件。 - Peter K
我99%肯定你錯了。您能提供任何證據來支持您的索賠嗎? - Scott
是的,看起來我確實錯了。找... +似乎打破了多行命令,好抓! - Peter K


試試這個python腳本;它不需要產生進程,每個文件只需要兩個系統調用。 除了在C中的實現,它可能是最快的方式(我需要它來修復1500萬個文件的文件系統,這些文件系統都被設置為777)

#!/usr/bin/python3
import os
for par, dirs, files in os.walk('.'):
    for d in dirs:
        os.chmod(par + '/' + d, 0o755)
    for f in files:
        os.chmod(par + '/' + f, 0o644)

在我的例子中,最後一個chmod需要try / catch,因為chmodding一些特殊文件失敗了。


0
2018-03-26 04:37





你也可以使用 tree

tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'

如果你還想查看文件夾添加迴聲

 tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'

-1
2018-02-16 09:34



@Scott 1)你是對的+ x我改為755; 2)3)解決這個問題我把佔位符放在單引號中,就像這個'{}' - Eduard Florinescu
@Scott我同意這不是最好的答案也很慢但是會留在這里為“教學”目的而且評論會進一步解釋,人們也可以了解一下 xargs 的問題。文件名中的單引號本身就是許多命令和腳本的問題,這就是我列出包含單引號的所有文件並將其刪除的原因(我的意思是引號) - Eduard Florinescu
@Scott在我的系統上,我搜索了包含單引號的所有文件並替換了單引號 - Eduard Florinescu
@Scott你如何解決xargs無法正確解決單引號的事實? - Eduard Florinescu
讓我們 在聊天中繼續討論。 - Eduard Florinescu


您可以使用以下bash腳本作為示例。一定要給它可執行權限(755)。只需使用./autochmod.sh作為當前目錄,或./autochmod.sh <dir>指定另一個目錄。

#!/bin/bash

if [ -e $1 ]; then
    if [ -d $1 ];then
        dir=$1
    else
        echo "No such directory: $1"
        exit
    fi
else
    dir="./"
fi

for f in $(ls -l $dir | awk '{print $8}'); do
    if [ -d $f ];then
        chmod 755 $f
    else
        chmod 644 $f
    fi
done

-2
2018-01-29 11:56



哇!這麼多問題! (1)如果 $1 不是null,但不是目錄的名稱(例如,是一個錯字) dir 設置為 . 沒有消息。 (2) $1 應該 "$1" 和 $dir 應該 "$dir"。 (3)你不需要說 "./"; "." 很好(嚴格來說,這裡你不需要引號)。 (4)這不是遞歸解決方案。 (5)在我的系統上, ls -l … | awk '{ print $8 }' 獲取文件的修改時間。你需要 { print $9 } 要得到 第一個字 文件名。即使這樣,(6)這也不能處理帶有空格的文件名。 ... - Scott
...最後但並非最不重要(∞)如果此腳本在當前目錄中,它將會 chmod  本身 至644,因此使自己不可執行! - Scott