web-dev-qa-db-ja.com

`rm -rf`を実行する場合、特定のサブディレクトリを除外することはできますか?

私は日常的にバインドマウントを使用して、複数の論理ボリューム/物理パーティション/ LUNなどを使用せずに、複数の場所でスペースを利用できるようにしています。

たとえば、/spaceに200GLVをマウントしているとします。そこから、var_optvar_logのようなサブディレクトリを作成し、マウントをそれぞれ/var/opt/var/logにバインドできます。

'space'ディレクトリでクリーンアップを行う場合、rm -rf内で実行されている/spaceからディレクトリを除外することは可能ですか?

例:

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

私がやろうとしていることを達成するために、私が考えていなかった別の、またはより良い(しかし同様に単純な)方法はありますか?

5
warren

たぶんfind + xargs + rmの組み合わせで?

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

またはその曲の何か。もちろん、rmに変更する前に、まずxargsにechoなどのより無害なものを実行するように指示するのが賢明かもしれません...

1

概念的に単純で、エラーのリスクが低い:

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

Kshの拡張グロブを使用することもできます。

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)

入力ファイル名がユーザーによって生成された場合、ファイル名にスペース、 '、または "を含む意外なファイル名を処理する必要があります。

xargsを使用すると、 セパレータの問題 が原因で、厄介な驚きが生じる可能性があります。

GNU Parallel その問題はありません。

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

詳細については、 GNU Parallel の紹介ビデオをご覧ください。

2
Ole Tange

保存したいディレクトリが正確にマウントポイントである場合は、GNU rm--one-file-systemを使用できる可能性があります。

私はこれがどのように実装されているかを調査していませんが、バインドマウントが同じファイルシステム内からのものである場合、これはあなたが望むことをしないと推測していますので、注意してください! rmには--no-actオプションはありませんが、たとえばyes no | rm -ir .をパイプすることができます。

1
Toby Speight