我想撰寫一個對多個檔案進行操作的 shell 腳本,并且(除其他外)將使它們可執行。
問題:這些檔案有不同的權限——特別是,有些是所有用戶都可以讀取的,有些只能由所有者讀取——我想為那些擁有讀取權限的人添加執行權限(也就是說,如果所有人都可以讀取檔案,所有人都應該能夠執行它,但是如果只有所有者可以讀取它,那么只有所有者應該能夠執行它)。
我知道如何通過使用任意數量的編程語言撰寫一個小程式并使用幾種不同的方法來實作這一點(從對每個代理權限的簡單、直接的條件到巧妙地使用屏蔽和權限轉移)位),但我想在“純”shell腳本中實作這一點,只使用標準shell命令和Unix utils。
更新:目前有兩個答案,這兩個答案都暗示了有趣的技術(使用zsh的 glob 限定符和 using find),這些技術似乎與我需要的東西密切相關,但作為我面臨的挑戰,略微忽略了問題的重點沒有找到要處理的檔案:腳本的用戶會告訴它要處理哪些檔案。相反,挑戰是給定一個特定檔案,例如,chmod o x根據是否o r已設定權限來決定是否呼叫它。
uj5u.com熱心網友回復:
如果zsh用作您的 shell,您可以利用glob 限定符將匹配限制為具有和不具有特定權限位的檔案:
# chmod all plain files (.) that are world-readable (R) but not world-executable (^X)
zsh$ chmod o x *(.R^X)
# files that are owner-readable but not owner-executable
zsh$ chmod u x *(.r^x)
# And groups
zsh$ chmod g x *(.A^E)
您還可以執行諸如*(.X^R)獲取全域可執行但不可讀的檔案之類的操作,或者獲取具有權限(在 之前^)和沒有權限(在 之后)的其他組合^。還有一個ffspec限定符,可以更好地控制權限位匹配;有關詳細資訊,請參閱檔案。
要獲取目錄樹中的所有檔案而不僅僅是當前目錄,請使用**/*代替*.
uj5u.com熱心網友回復:
這可能不是最有效的方法,但我真的很喜歡這個find命令的直觀 API。
以下命令查找當前目錄(.)中組或所有用戶可讀的所有檔案和目錄:
find . -perm /go=r
此命令查找所有者可讀但組或所有用戶不可讀的所有檔案和目錄:
find . -perm /u=r ! -perm /go=r
找到要處理的檔案后,您可以添加一個-exec引數以對每個匹配項執行命令。例如,以下命令將在所有只能由所有者讀取的檔案和目錄上設定所有者的可執行位:
find . -perm /u=r ! -perm /go=r -exec chmod u x {} \;
該行的結尾很奇怪,但完全按照所示輸入它,它應該可以作業。
此命令將在組和其他人可讀的所有檔案和目錄上設定“組”和“其他”的可執行位:
find . -perm /go=r -exec chmod go x {} \;
所有這些命令都在當前目錄中遞回搜索。.您可以通過替換為其他路徑來指定任意其他目錄。
您還可以指定搜索的深度-maxdepth N。
編輯:
如果要處理單個指定檔案,可以使用以下腳本。它使用stat命令檢查檔案的權限,該命令以類似于ls -l顯示的格式回傳權限,例如-rw-r--r--.
myfile="/tmp/abc"
permissions="$(stat -c %A $myfile)"
if [[ "$permissions" =~ ^....r.....$ ]] || [[ "$permissions" =~ ^.......r..$ ]]; then
# file is readable by group and/or others
# set executable bit for owner, group and others
chmod a x "$myfile"
elif [[ "$permissions" =~ ^.r........$ ]]; then
# file is note readable by group or others
# Set executable bit for owner only
chmod u x "$myfile"
fi
該腳本適用于 bash 和 zsh。
uj5u.com熱心網友回復:
到目前為止提供的答案提供了有用的想法,但是,由于他們都沒有按要求回答問題,因此我特此發布我自己問題的答案。
該答案提出了三種不同的解決方案,每種解決方案都基于先前發布的答案中建議的不同方法;還有其他未涵蓋的方法(我只提到,不顯示實際代碼,將權限作為八進制數的技巧,然后 - 使用一些執行算術/按位計算的機制 - 和它with444得到r位,右移 2 位得到對應的x位,與原始權限 oring,并將結果設定為新權限)。
以下所有解決方案都假定處理檔案"$FILE"。
解決方案 1 -if將當前權限的模式作為文本
這可能是最直接的方法:
permissions=$(stat -f %SA "$FILE")
if [[ $permissions =~ .r........ ]]; then chmod u x "$FILE"; fi
if [[ $permissions =~ ....r..... ]]; then chmod g x "$FILE"; fi
if [[ $permissions =~ .......r.. ]]; then chmod o x "$FILE"; fi
解決方案 2 – 使用find,利用-perm和-exec選項
這種方法find不使用查找多個檔案,而是查找給定檔案(如果它具有特定權限)或不查找任何內容(否則),并在找到檔案時設定匹配的所需權限(并且否則什么都不做):
find "$FILE" -perm -u=r -exec chmod u x {} \;
find "$FILE" -perm -g=r -exec chmod g x {} \;
find "$FILE" -perm -o=r -exec chmod o x {} \;
這三種情況可以很容易地組合成一個for回圈:
for w in u g o; find "$FILE" -perm -$w=r -exec chmod $w x {} \;; done
解決方案 3(zsh僅限) - 使用 glob 限定符
這種方法僅在它已經匹配相應權限的情況下運行每個相關chmod命令。"$FILE"添加注釋|| :是為了避免在不匹配的情況下出現錯誤,即如果檔案沒有相應的權限(在這種情況下,注釋zsh仍然會發出no matches found警告):
chmod u x "$FILE"(r) || :
chmod g x "$FILE"(A) || :
chmod o x "$FILE"(R) || :
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/444737.html
