rm -rf
変数が設定されていないため、それを使用する危険な経験をしました。それ以来、rm -rf
文を書きながらスペルミス、浮き書きなどを何度も交差確認しました。
これまで、私はできるだけ次の慣行に従いました。
- ルート以外のユーザーを使用してください。
*
より具体的なファイルパスを使用または使用しないでください。- 変数をディレクトリ名として使用しないでください。
したがって、私が使用できる標準/推奨ケース、方法、またはスクリプトがあるかどうか疑問に思いますrm -rf
。特に*
スクリプトに手動エラーがある場合は破壊的ではありません。
修正する:
特定のディレクトリを空にするための永続的なbashユーティリティがここに作成されます。https://github.com/g1patnaik/system_utilities/tree/dev/empty_directory
答え1
私はこの質問が回避に関するものであるとは思わないがrm -rf
、操作上安全でない状態で終わったり、不確実な結果を招くような方法での使用を避けることに関するものです。スペルエラーに関しては、次のようなものを使用できます。shellcheck
特定のシェル変数(、、、などfailglob
)を設定します。それでも、最終的にはコードを読み、実行する前に使い捨てまたはバックアップデータでテストする習慣を持ちます。bash
nounset
仕事を複雑すぎるのは役に立たないと思います。すべてのディレクトリコンテンツを削除する場合は、最も簡単な方法はディレクトリを完全に削除して再作成することです。
rm -rf -- "$directory" && mkdir -p -- "$directory" || exit
引用符を参照してください$directory
。それ以外の場合は、文字列が$directory
用語に分割され、foo bar
コードから両方の名前foo
と変数の値が削除されるため、これが必要ですbar
。これらの単語はファイル名のワイルドカードパターンに拡張されるため、literalというディレクトリを削除することは危険になります *
。実際のディレクトリ名の前に解析するには、to endオプションを使用して、たとえば、またはという名前のディレクトリを--
処理できます。-f
--version
失敗した場合は、exit
上記の操作を実行します。コードは、自然に再生成されたディレクトリのすべての所有権とその他のメタデータもリセットします。rm
mkdir
別の方法はを使用することですfind
。
find "$directory/." ! -name . -delete
上記は非標準ですが、一般的に実装されている-delete
述語を使用します。find
ディレクトリ自体を除いて、そのディレクトリの下のすべてのエントリを削除します。この場合、元のディレクトリエントリは再生成されず、そのまま残ります。
Portableでは、find
次のように書くことができます。
find "$directory/." -depth ! -name . -exec rm -rf {} +
cd -
コードは最初に失敗しても実行されるため、cd
スクリプトが予期しない作業ディレクトリに残っている可能性があります。さらに、コードは隠された名前を削除することができず、globbingパターンがあまりにも多くの名前に展開されると、「パラメータリストが長すぎます」というメッセージで失敗します。一致するものがない場合(またはそれに対応する)、シェルオプションセットを使用してスクリプトの実行を*
終了しますfailglob
(ディレクトリが空ではないと予想されますが、実際には空の場合はこれは良いことです)。
答え2
結局のところ、不要なrm -rf
代替パターンや安全な場所を見つけるのも良い考えです。
たとえば、mktemp
関数ローカル変数へのパスを広範囲に保存することで、すべてを自動的にクリーンアップできます。未知のファイルのツリー全体をプロセスに収集しないと、そのファイルはまったく必要ないかもしれません。
/
ツリーを収集する場合は、変数が誤ってゼロになってもクリアされないように、作業パスに固定接頭辞があることを確認できます。
答え3
空の変数に対する最も簡単で一般的な保護は、rm -rf
変数が空でないことを確認することです。
if [ -n "$directory" ]; then
rm -rf "$directory"
fi
デフォルトパスに追加する場合、これはデフォルトパスのみを渡して、意図したものよりはるかに多くを削除しないようにする重要なチェックです。次の例を考えてみましょう。
rm -rf "/home/user/$Dir"
変数が$Dir
空の場合、コマンドはですrm -rf /home/user/
。
-f
削除する項目について詳しく知っている場合は、パスがファイルまたはディレクトリであることを確認することもできます-d
。
man test
式のテストに関するほとんどの情報については、参考資料を参照してください。
引用符はパス名を2つのパラメータに分割し、パス名にスペースが含まれないようにします。