如何通過該目錄的名稱更改目錄的所有者和組?
我有一個 Ubuntu 16.04 Nginx 伺服器環境,在文件根目錄下有幾個 CMS (WordPress) 網站。
所有站點目錄都
www-data
以遞歸方式作為所有者和組。根據我得到的一些安全諮詢,這是有問題的,因為來自一個站點的數據可能會改變任何其他相鄰站點(例如,安裝在其中一個站點的 CMS 中的惡意模組)。
我認為解決方案是更改此命令,該命令在添加新站點後始終執行(並且在更改所有者和組的更新後也在 cron 中):
chown -R www-data:www-data /var/www/html/*
對於一些條件命令,這些命令不僅將這些特徵更改
www-data
為站點目錄的實際名稱,而且還更改為站點目錄的實際名稱。為了澄清,每個站點目錄的所有者應該是
domain.tld
,組也應該是domain.tld
(我總是根據站點的 domain.tld 命名站點目錄)。什麼可能是這樣的條件命令?
注意:Nginx 使用者和目錄
/var/www/html/
都將保留在www-data:www-data
.G-Man更新:
我還沒有測試,但我認為如果你
${domain}
作為變數 ($1
) 的第一個參數傳遞,這很好:chown -R ${domain}:${domain} ${domain}/*
雖然我會保留它:
chown -R ${domain}:www-data ${domain}/*
當然,
adduser ${domain} --disabled-password --disabled-login
之前是需要的,如果沒有做過。
我可能遺漏了一些東西,但這看起來很簡單:
$ cd /var/www/html $ for dir in * do chown -R "$dir:$dir" "$dir" done
如果您擔心這些命令的正確性,可以在之前插入單詞,例如,
echo
chown
$cd/var/www/html $ 用於 * 中的目錄 做 **echo** chown -R "$dir:$dir" "$dir" 完畢
讓它告訴您它將執行哪些
chown
命令,而無需實際執行它們。這個技巧適用於整個答案,事實上,適用於大多數 shell 腳本解決方案(即,其他問題)。如果你想在一行中完成,
$ cd /var/www/html && for d in *; do chown -R "$d:$d" "$d"; done
我這樣做是
cd
為了避免其他答案所包含的複雜性。如果你這樣做
$ for dir in /var/www/html/*
then
dir
將被設置為/var/www/html/domain1
,/var/www/html/domain2
,/var/www/html/domain3
等,這對於操作目錄很好,但不會為您提供所需的使用者名和組名chown
。另一個答案使用了一個相當複雜(並且不完全可靠)awk
的過程來將目錄路徑的最後一級(即目錄名稱,也是使用者名;例如,domain1
)與路徑的其餘部分分開。幸運的是,我們可以完全在 shell 中做同樣的事情(但更好一些),就像這樣:$ for dir in /var/www/html/* do owner="${dir##*/}" chown -R "$owner:$owner" "$dir" done
${dir##*/}
是一種特殊形式的參數擴展 ,它獲取$dir
並刪除所有內容,直到(包括)最後一個/
(斜杠)字元。當然,這僅留下目錄基名,即使用者名,因此我們將其分配給owner
並在chown
命令中使用。請注意,此程式碼是POSIX 兼容的 ,應該可以在任何 POSIX 兼容的 shell 中工作;與本網站上的一些答案不同,它不依賴於 bash。如果您想在一行中執行此操作,
$ for d in /var/www/html/*; do o="${d##*/}"; chown -R "$o:$o" "$d"; done
當然,如果您只是不想更改主 shell 的工作目錄,那麼您可以在子 shell 中執行第一個命令:
$ (cd /var/www/html && for d in *; do chown -R "$d:$d" "$d"; done)
不言而喻(但我還是會這麼說)這要求您在執行任何這些命令之前定義名為
domain1
、domain2
、等的使用者(和組)。domain3
如果您有一個添加新站點的腳本,那麼在創建新目錄之前添加一個命令以創建新使用者是一件簡單的事情,然後再執行chown
. 如果您chown
使用不是已定義使用者名的名稱執行,它將給您一條invalid user
錯誤消息。