rmコマンドとmvコマンドの事故に備えた安全な使い方

最近rmコマンドやmvコマンドによる悲劇を観測してしまったので、これを機に今までに観測したことのある事例と対策をメモしておく。

まとめ

さきにまとめ。

rmコマンドの使い方

  • 原則として-ivオプションを付与する。操作に使うシェルにはエイリアスで設定しておくとよい。
    • -iの目的:削除前に確認することで、意図しないファイルの削除を防止する
    • -vの目的:削除したファイルを表示することで、意図しないファイル削除に気付く機会を作る
  • -f-rfは極力付けず、必要な場合のみ指定する。指定する場合は末尾のパラメータとして入力する(環境依存あり1
    • 目的:意図しないファイルの削除を防止する
    • 目的:シンボリックリンク先の実体ディレクトリを丸ごと削除してしまうことを防止する

mvコマンドの使い方

  • 原則として-ivオプションを付与する。シェル設定にはエイリアスで指定しておく
    • -iの目的:上書き前に確認することで、意図しないファイルの上書きを防止する
    • -vの目的:移動したファイルを表示することで、意図しないファイル移動に気付く機会を作る

事故の事例

rmで前方部分一致するファイルやディレクトリを誤って削除してしまった

事例

delete_targetを削除しようとしている状況で、以下のように[Tab]の補完を実行する。

% ls
delete/        delete_target
% rm -rf del[Tab]

すると、以下のように補完される。

% rm -rf delete
もしこのまま勢いでEnterを押してしまえば、当然ながら削除されるのはdeleteディレクトリである。

事例2

他に、Emacsのバックアップファイルを削除する場合が挙げられる。

Emacsはファイル名の末尾にチルダの付いたバックアップファイルを作成するため、これを削除する場合は以下のようにコマンドを実行する。

% rm -rf *~
しかし以下のような誤入力をすると、バックアップファイルを削除しようとした結果、マスターを削除してしまうという大惨事となる。
% rm -rf *[ここで~を入力しようとしてEnter]

そんなことがあるのかと思うかもしれないが、チルダはShiftキーを使って入力するため、右Shiftキーを押下する際に誤ってEnterを押せば、この事故は成立してしまう。

学ぶべきこと

ここから学ぶべきことは以下の6点。

  1. 未然防止:原則として-iを指定し、削除の確認を表示させる
  2. ミス検知:原則として-vを指定し、削除した対象ファイルを表示させることで、ミスに気付く機会を作る
  3. 仕組み化:-i-vをエイリアスで指定しておく
  4. リスク軽減:操作ミスを前提に考え、不必要に-f-rfを指定しない。
  5. リスク低減:-f-rfオプションが必要な場合は、可能であれば末尾のパラメータとして指定する
  6. リスク低減:右ShiftキーはEnterを誤爆する可能性があるので危険。普段から左Shiftを意識する

何を削除するにしてもrm -frm -rfと入力するのを見かけることがあるが、これは絶対に避けるべきである。
なお、5.についてはMac上で試した結果、-rfを末尾に付けてもオプションとして認識されなかったため、環境依存と思われる点に注意。

rmでシンボリックリンク先のディレクトリを削除してしまった

透過的にファイルやディレクトリを扱うことができるシンボリックリンクだが、削除する際には事故のリスクがある。

事例

例えば、以下のコマンドを入力すると~/temp/directoryにディレクトリを作成した後、directoryへのシンボリックリンクが作成される。

mkdir -p ~/temp/directory # ~/temp/directory/を作成する
ln -s ~/temp/directory    # directoryへのシンボリックリンクを作成する
この後、以下のコマンドを実行するとシンボリックリンクが削除される。
rm directory              # シンボリックリンクを削除する
しかしここで、誤って以下を入力すると、シンボリックリンク先のdirectory自体が削除される。
rm -rf directory/         # リンク先のdirectory自体を削除する
このようなケースではシンボリックリンクの末尾に/を付けるかどうかにより、削除対象が大きく変わってしまう。

学ぶべきこと

ここから学ぶべきは3つ。

  1. リスク軽減:不必要に-rfオプションを付けないこと。シンボリックリンクを削除する際に、このオプションは不要。
  2. リスク軽減:ファイルやディレクトリには最小限のアクセス権を設定すること。シンボリックリンクに限らず、削除権限がなければ、誤って削除されることはない。
  3. リスク低減:無計画にシンボリックリンクを作ったり、削除リスクの高いディレクトリへのリンクを作成しない。

Linux系の環境に慣れてくるとシンボリックリンクを使い始めるようになるが、その時にやらかしがちなので注意。

mvのパラメータにワイルドカードを指定してしまった

事例

ワイルドカードを含むmvコマンドを実行する際、タイプミスや誤ってEnterを押下した場合には被害が大きくなり得る。
極端ではあるが、具体例としては以下のコマンドを実行してしまったケース。

mv *
この実行結果は、現在のディレクトリ構成によって異なる。

ワイルドカードによって展開された末尾のパラメータがファイルであれば、mvコマンドは以下のようにエラーで終了する。
これは結果としては、かなりマシなほうである。

# ワイルドカードによって展開された末尾のパラメータがファイルの場合
% ls
file1  file2  file3
% mv *
usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory

悲惨なのは、ワイルドカードによって展開された末尾のパラメータがディレクトリの場合。
この場合、ワイルドカードによって展開された末尾ののディレクトリに、すべてのファイルが移動されることになる。
しかも、実行時には何も表示されないため何が発生したかは気づきにくい。

# ワイルドカードによって展開された末尾のパラメータがディレクトリの場合
% ls
file1        file2        file3        z_directory/
% mv *  # mvは実行されるが、ターミナルには何も表示されない

学ぶべきこと

ここから学ぶべきこととしては、以下の3点。

  1. ミス検知:原則-vオプションを指定し、ファイル移動処理の結果を表示させる
  2. 未然防止:原則-iオプションを指定し、上書き時は警告を表示させる
  3. 仕組み化:-i-vをエイリアスで指定しておく

mvrmと比べて油断されやすいが、指定したパスからファイルが失われるという点では同じである。
しかしそれに加えて、mv-iオプションではカバーしきれないことに注意が必要である。
rm -iでは毎回削除前に確認が表示されるが、mv -iでは上書きとならない限り警告が表示されないため、ミスタイプによって気付かぬうちにファイルやディレクトリが行方不明になることは防ぎきれない。
そのため、-vオプションによってミスに気付く機会を与えることが特に重要となる。

なお、mv-ivオプションを付けて実行した場合、以下のようになる。

# mvに-ivオプションをつけることで、リスクを緩和できる
% ls
file1        file2        file3        z_directory/
% mv -iv *  # -vオプションのおかげで、どんな移動が行われたかが表示される
file1 -> z_directory/file1
file2 -> z_directory/file2
file3 -> z_directory/file3
% touch file1 file2 file3
% ls
file1        file2        file3        z_directory/
% mv -iv *  # -iオプションのおかげで、上書きの警告が表示される
overwrite z_directory/file1? (y/n [n]) 
not overwritten
overwrite z_directory/file2? (y/n [n]) 
not overwritten
overwrite z_directory/file3? (y/n [n]) 
not overwritten


  1. Macのターミナルでは、-rfを末尾につけるとオプションとして認識されず、ファイル名として認識された ↩︎

関連記事


  1. Macのzsh上でFn-Deleteが動作しない問題
  2. Debianでパスワードを忘れたときの対処法
  3. Open Session in Viewは使用すべきなのか?
  4. Singleton パターン
  5. イミュータブルオブジェクト
  6. Strategy パターン
  7. Factory Method パターン

comments powered by Disqus