題 運行`rm -rf`時,是否可以排除某些子目錄?


我經常使用綁定掛載來幫助在多個位置提供空間,而無需擁有多個邏輯卷/物理分區/ LUN等。

例如,我可能安裝了200G LV /space。從那裡,我將使子目錄像 var_opt 和 var_log 然後我可以將mount綁定到 /var/opt 和 /var/log, 分別。

在'space'目錄上進行清理時,是否可以 排除 來自的目錄 rm -rf 在裡面跑 /space

例:

# pwd
/space
# rm -rf * {except-for-var_opt-and-var_log}

是否有一種不同的或更好的(但同樣簡單的)方式來完成我想要做的事情,我沒想到過?


4
2017-09-28 13:12


起源




答案:


也許與find + xargs + rm組合?

find /space ! -iregex '(var_opt|var_log)' | xargs rm -f

或那種曲調中的東西。當然,在將其更改為rm之前,首先指示xargs執行更無害的事情(例如echo)可能是明智的。


1
2017-09-28 13:16



沒想到這個!好主意 :) - warren
不要使用xargs (除了 -0)!它期望以非常特殊的方式引用輸入 find 沒有產生。因此,如果文件名包含空格或,則此命令將失敗 \'"。相反,使用 -exec:找/空間! -iregex'(var_opt | var_log)' - exec rm {} +. Or since -iregex`無論如何都是特定於GNU查找,使用它 -delete 行動: find /space ! -iregex '(var_opt|var_log)' -delete。 - Gilles


概念上簡單,並且具有較低的錯誤風險:

mkdir TO_DELETE
mv * TO_DELETE
mv TO_DELETE/var_opt TO_DELETE/var_log .
rm -rf TO_DELETE

你也可以使用ksh的擴展globs:

rm -rf !(var_opt|var_log)

如果啟用它們,它們也可以在bash中使用:

shopt -s extglob
rm -rf !(var_opt|var_log)

在zsh中同上:

setopt ksh_glob
rm -rf !(var_opt|var_log)

Zsh也有自己的擴展球:

setopt extended_glob
rm -rf ^var_(opt|log)

11
2017-09-28 23:10





如果輸入文件名由用戶生成,則需要處理 令人驚訝的文件名包含文件名中的空格,'或“。

指某東西的用途 xargs 因為這會導致令人討厭的驚喜 分隔符問題

GNU Parallel 沒有那個問題。

find /space ! -iregex '(var_opt|var_log)' | parallel -X rm -f

看著 GNU Parallel的介紹視頻 了解更多。


2
2017-09-28 22:47





如果要保留的目錄完全是掛載點,則可以使用 --one-file-system 在GNU rm

我還沒有調查過這是如何實現的,但是我猜想如果綁定掛載來自同一個文件系統,這將不會做你想要的,所以要小心! rm 沒有 --no-act 選項,但你可以管道 yes no | rm -ir . 例如。


1
2018-04-27 16:47