次のコマンドを使用してサブボリュームセットを見つけて削除します。
find /.snapshots/ -name backup-* -type d -exec btrfs subvolume delete {} \;
うまくいきますが、findで予期しない結果が表示されます。
Delete subvolume (no-commit): '/.snapshots/backup-24-11-2021'
find: ‘/.snapshots/backup-24-11-2021’: No such file or directory
Delete subvolume (no-commit): '/.snapshots/backup-25-11-2021'
find: ‘/.snapshots/backup-25-11-2021’: No such file or directory
私はUnixの専門家ではないので、これは少し混乱しています。なぜこれが起こるのですか?
答え1
find
が到着したら、/.snapshots/backup-24-11-2021
の指示に従ってディレクトリであることを確認してください-type d
。ディレクトリなので、指示に従ってくださいfind
。完了すると、ディレクトリに到達したばかりで、そのディレクトリに戻ります。結局、ディレクトリへの再帰は.しかし、そのディレクトリはちょうど削除されました。したがって、問題を発見して報告してください。btrfs subvolume delete /.snapshots/backup-24-11-2021
-exec …
find
find
btrfs subvolume delete
find
find
削除したいスナップショットの下で繰り返さないように指示します。これは通常、削除するディレクトリツリー全体を検索するために使用されます。
find /.snapshots/ -name 'backup-*' -type d -exec btrfs subvolume delete {} \; -prune
(注:句の周りに欠落している引用符も修正されました。引用-name
符がないとbackup-*
実行時に拡張されるため、現在のディレクトリに一致するファイルがある場合、または使用中のシェルにエラーがある場合、コマンドは操作を実行しません。グローバルに一致しませんとfind
予想backup-*
しかし、実際にはこれは完全に間違ったコマンドかもしれません。find
以下を見てください/.snapshots
。たとえば、/.snapshots/saved-for-posterity/usr/src/backup-app
コマンドがfind
call で指示するディレクトリがある場合、btrfs subvolume delete /.snapshots/saved-for-posterity/usr/src/backup-app
これは意味がありません。すべてのスナップショットがのサブディレクトリであると仮定し、追加の再帰を防ぐには、次のように渡し/.snapshots
ます。-maxdepth 1
find /.snapshots/ -maxdepth 1 -name 'backup-*' -type d -exec btrfs subvolume delete {} \;
唯一の違いは
btrfs subvolume delete /.snapshots/backup-*
現在バックアップがない場合は、btrfs subvolume delete
リテラルパラメータとして呼び出されます。/.snapshots/backup-*
答え2
find
ディレクトリ内を調べる前にディレクトリを削除したため、エラーメッセージが表示されます。find
現在削除されているディレクトリを含むディレクトリ操作が完了すると、egを入力しようとしますが、そのディレクトリが消えたbackup-24-11-2021
ため、「ファイルまたはディレクトリが見つかりません」というエラーで失敗します。
ユーティリティがディレクトリに対して深さ優先検索を実行するようにするwithを使用して、-depth
この問題を解決できます。たとえば、検索と削除は、そのfind
パスの下の他のすべてのディレクトリを表示した後にのみ発生します。/.snapshots/backup-25-11-2021
find
find /.snapshots -depth -name 'backup-*' -type d \
-exec btrfs subvolume delete {} \;
-name
また、ファイル名にワイルドカードが含まれているため、テストパラメータを引用する必要があります。
これを行うもう1つの方法は、パスが見つかると検索ツリーからそのパスを削除して、そのパスに深く入ろうとしないようにする-prune
ことです。find
find
find /.snapshots -name 'backup-*' -type d -prune \
-exec btrfs subvolume delete {} \;
3番目のアプローチは、すべてのbackup-*
ディレクトリが常に次のすぐ下にある場合です/.snapshots
。find
shopt -s nullglob
for dir in /.snapshots/backup-*; do
btrfs subvolume delete "$dir"
done
btrfs subvolume delete
上記のシェルループは、パターンに一致するすべてのディレクトリを呼び出します/.snapshots/backup-*
。bash
シェルでnullglob
シェルオプションを設定すると、シェルは拡張されていないパターンを残さず、一致しないワイルドカードパターンを削除します。
コマンドがbtrfs subvolume delete
複数のパス名を引数として使用できる場合は、次のようにする必要があります。
shopt -s failglob
btrfs subvolume delete /.snapshots/backup-*
...指定されたワイルドカードパターンと一致するパス名がない場合、シェルのfailglob
シェルオプションはコマンドの実行を防ぎます。bash