如何使用缺少-exec的查找遞歸設置目錄權限?
我的 Qnap NAS 被一個
find
缺少-exec
參數的命令所詛咒,所以我必須通過管道傳輸一些東西。外殼是:GNU bash,版本 3.2.57(2)-release-(arm-unknown-linux-gnueabihf)我正在嘗試在目前目錄的所有子目錄(不是文件)上設置 setgid 位。
這不起作用:
find . -type d | xargs chmod g+s $1
使用
"$1"
,"$(1)"
等$("1")
也不行。它們都表明chmod
正在傳遞一個包含空格作為兩個或多個參數的目錄名稱(它會吐出有關支持哪些參數的標準幫助消息)。如果不需要,我不在乎使用
xargs
;我認為它無論如何都會被長名字窒息,不是嗎?這些及其變體不起作用:
find . -type d | chmod g+s find . -type d | chmod g+s "$1"
我曾考慮過使用
awk
或sed
註入引號,但我必須認為有一種更簡單的方法可以做到這一點。人們以前是做什麼的-exec
?(可悲的是,我可能早在 1995 年左右就知道了,但早就忘記了。)PS:這些目錄名稱中的許多將包含Unicode字元,
?
符號等。它們最初來自macOS,這是相當寬鬆的。也就是說,我可能應該?
用 Unicode 字元之類的東西替換所有實例,⁇
這樣 Windows 就不會阻塞它們。但這也需要對find
這個 crippleware 版本的find
.
的輸出
find
發出由換行符分隔的文件名1。這不是xargs
想要的格式,find
也無法生成xargs
想要的格式:它將輸入解析為空格分隔的項目,\'"
用於引用。某些版本xargs
可以採用換行符分隔的輸入,但如果您find
缺少標準選項,那麼您可能xargs
也會這樣做。
find . -type d | xargs chmod g+s
只要您的目錄名稱不包含空格或\'"
. 請注意,沒有$1
: 這對 shell 有意義,但沒有 shell 參與解析 的輸出find
並將其提供給chmod
, 只有xargs
.如果您的
find
has-print0
和 yourxargs
has-0
,您可以使用這些選項傳遞以空分隔的文件名,該文件名適用於任意文件名。find . -type d -print0 | xargs -0 chmod g+s
如果您
xargs
支持標準選項-I
,則可以使用它來指示它將每一行作為一個項目處理,而不是用空格分隔的引號字元串。這適用於空格,但不適用於\"'
換行符。find . -type d | xargs -I {} chmod g+s {}
您可以使用 shell 來遍歷行而不是
xargs
. 這適用於任何不包含換行符的文件名。find . -type d | while IFS= read -r line; do chmod g+s "$line"; done
這兩種解決方案都只適用於不包含換行符的文件名。包含換行符的文件名的輸出
find
是模棱兩可的,除非在一種難以解析的情況下:find
不會自發地發出多個斜杠,因此如果您//
輸入要遍歷的目錄的路徑,您可以在輸出中辨識出這一點。這是一些經過最低限度測試的程式碼,它使用這個事實將輸出find
從xargs
.chars=$(printf '\t "'\\\') { find .//. -type d; echo .// } | LC_ALL=C sed -n ' s/['"$chars"']/\\&/g /^\.\/\// { x s/\n/\\&/g p b } H' | LC_ALL=C xargs chmod g+s
1 更準確地說:由換行符終止(姓氏後有換行符)。