Bashスクリプトでrm -rfを使用しないようにするには?

Bashスクリプトでrm -rfを使用しないようにするには?

rm -rf変数が設定されていないため、それを使用する危険な経験をしました。それ以来、rm -rf文を書きながらスペルミス、浮き書きなどを何度も交差確認しました。

これまで、私はできるだけ次の慣行に従いました。

  • ルート以外のユーザーを使用してください。
  • *より具体的なファイルパスを使用または使用しないでください。
  • 変数をディレクトリ名として使用しないでください。

したがって、私が使用できる標準/推奨ケース、方法、またはスクリプトがあるかどうか疑問に思いますrm -rf。特に*スクリプトに手動エラーがある場合は破壊的ではありません。

修正する:

特定のディレクトリを空にするための永続的なbashユーティリティがここに作成されます。https://github.com/g1patnaik/system_utilities/tree/dev/empty_directory

ベストアンサー1

私はこの質問が回避に関するものであるとは思わないがrm -rf、操作上安全でない状態で終わったり、不確実な結果を招くような方法での使用を避けることに関するものです。スペルエラーに関しては、次のようなものを使用できます。shellcheck特定のシェル変数(、、、などfailglob)を設定します。それでも、最終的にはコードを読み、実行する前に使い捨てまたはバックアップデータでテストする習慣を持ちます。bashnounset

仕事を複雑すぎるのは役に立たないと思います。すべてのディレクトリコンテンツを削除する場合は、最も簡単な方法はディレクトリを完全に削除して再作成することです。

rm -rf -- "$directory" && mkdir -p -- "$directory" || exit

引用符を参照してください$directory。それ以外の場合は、文字列が$directory用語に分割され、foo barコードから両方の名前fooと変数の値が削除されるため、これが必要ですbar。これらの単語はファイル名のワイルドカードパターンに拡張されるため、literalというディレクトリを削除することは危険になります *。実際のディレクトリ名の前に解析するには、to endオプションを使用して、たとえば、またはという名前のディレクトリを--処理できます。-f--version

失敗した場合は、exit上記の操作を実行します。コードは、自然に再生成されたディレクトリのすべての所有権とその他のメタデータもリセットします。rmmkdir

別の方法はを使用することですfind

find "$directory/." ! -name . -delete

上記は非標準ですが、一般的に実装されている-delete述語を使用します。findディレクトリ自体を除いて、そのディレクトリの下のすべてのエントリを削除します。この場合、元のディレクトリエントリは再生成されず、そのまま残ります。

Portableでは、find次のように書くことができます。

find "$directory/." -depth ! -name . -exec rm -rf {} +

cd -コードは最初に失敗しても実行されるため、cdスクリプトが予期しない作業ディレクトリに残っている可能性があります。さらに、コードは隠された名前を削除することができず、globbingパターンがあまりにも多くの名前に展開されると、「パラメータリストが長すぎます」というメッセージで失敗します。一致するものがない場合(またはそれに対応する)、シェルオプションセットを使用してスクリプトの実行を*終了しますfailglob(ディレクトリが空ではないと予想されますが、実際には空の場合はこれは良いことです)。

おすすめ記事