Bash

如何使用缺少-exec的查找遞歸設置目錄權限?

  • May 24, 2021

我的 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"

我曾考慮過使用awksed註入引號,但我必須認為有一種更簡單的方法可以做到這一點。人們以前是做什麼的-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.

如果您的findhas-print0和 your xargshas -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不會自發地發出多個斜杠,因此如果您//輸入要遍歷的目錄的路徑,您可以在輸出中辨識出這一點。這是一些經過最低限度測試的程式碼,它使用這個事實將輸出findxargs.

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 更準確地說:由換行符終止(姓氏後有換行符)。

引用自:https://unix.stackexchange.com/questions/651000