Re: [問題] 關於bash指令

作者: kenduest (小州)   2016-05-04 01:37:58
※ 引述《ymzk ()》之銘言:
> 在網路上有看到一個方法可以把某個目錄下所有資料夾都變成群組可執行
> 指令如下
> sudo chmod g+x $(find ./ -type d)
$() 裡面可以放入要執行的命令,最後 find 命令透過 stdout 輸出的訊息
當作為 chmod g+x 傳入的檔案目錄名稱。
其實不建議這樣用,因為路徑若有空白這類情況時候會出錯
> 但我執行時會出現一些怪怪的訊息, 例如一些資料夾他說根本找不到
比方有個目錄名稱叫做 "My Documents" 來說,上面語法就變成:
sudo chmod g+x My Documents
一般要避免該問題有很多方式,比方:
find ./ -type d -exec chmod g+s {} \;
不過這語法效能很糟糕,因為有找到 10000 個項目就要呼叫 chmod 高達
10000 次,所以一般會改用:
find ./ -type d | xargs chmod g+s
其中 find 找到符合的列表會透過 stdout 輸出,xargs 能夠透過 stdin 讀入
剛剛 find 給的輸出結果,然後當作為執行 chmod g+s 要帶入的引數。所以這
語法基本上類似於 chmod g+s $(find ./ -type d)
當然上面那語法也會遇到檔案有空白等問題,有空白字元等檔名會被當作兩個
項目。所以一般使用會使用:
find ./ -type d -print0 | xargs -0 chmod g+s
其中 find 搭配 -print0 就是透過 stdout 輸出的列表內改用 NULL 字元當檔名
分隔,而不是使用原本一般的空白字元。而要呼叫 xargs 時候也要傳入 -0 告知
讀入的資料以 NULL 字元當分隔,如此就可以解決剛剛談到的問題。
find + xargs 基本上效能不錯,不過有時候 find 結果帶多可能會讓 xargs 在
帶入結果時候發生執行命令帶入引數發生 Argument list too long 的錯誤,一般
要避開可以這樣:
find ./ -type d -print0 | xargs -n 100 -0 chmod g+
就是一次處理單位為 100
> 另問一下這到底是什麼原理?
> 他是執行了很多chmod指令還是一個chmod指令後面帶了很長的參數?
> 如果是後者會不會因為太長而有部份失敗@@"
作者: niker (新月曲如眉)   2016-05-04 02:50:00
推小州老師講解。
作者: CP64 (( ̄▽ ̄#)﹏﹏)   2016-05-04 03:08:00
推 平時沒處理到那麼多還真的不會考慮到
作者: Neisseria (Neisseria)   2016-05-04 10:21:00
推小州老師講解
作者: chababa (洽八八)   2016-05-04 15:50:00
好強,謝謝分享
作者: filiaslayers (司馬雲)   2016-05-04 16:07:00
為什麼用xargs的效能會好過用exec參數?
作者: CP64 (( ̄▽ ̄#)﹏﹏)   2016-05-04 16:23:00
剛剛看了 find 的 manpage 說 \; 換成 + 也會有類似效果 @@
作者: danny8376 (釣到一隻猴子@_@)   2016-05-04 16:39:00
xargs其實很類似於$()的功能 不過xargs比較彈性
作者: soem (流水)   2016-05-04 22:43:00
是因為那個語法是把前面find找出來的pile給xargs後面接的指令,一次做完。這樣就不用call很多次exec後面的指令pipe 我打成了甚麼..
作者: Qiqi (潑潑)   2016-05-05 00:11:00
白話一點差不多就是chmod file1chmod file2chmod file3跟chmod file1 file2 file3的差別
作者: kenduest (小州)   2016-05-05 00:41:00
目前的 find 應該都可以吃 -exec {} + 語法這就的確與 xargs 行為類似,所以也不一定需要 xargs 了

Links booklink

Contact Us: admin [ a t ] ucptt.com