web-dev-qa-db-ja.com

ユーザーがrmとワイルドカードの間に誤ってスペースを入力しないようにする

意図:

rm -rf string*

問題:

rm -rf string *

最初のケースはrmの正当で一般的な使用法であり、小さなタイプミスは2番目のケースで多くの問題を引き起こす可能性があります。偶発的な末尾または先頭のワイルドカードからスマートに保護する簡単な方法はありますか?

29
bobdole

疑わしいと思われるコマンドをキャンセルするためにDEBUGトラップを書き込むことができます。以下、またはそれに類似したコードを~/.bashrcに追加できます。

shopt -s extdebug
checkcommand() {
  if [[ $BASH_COMMAND = 'rm -r'*' *' ]]; then
    echo "Suppressing rm -r command ending in a wildcard" >&2
    return 1
  fi
  # check for other commands here, if you like
  return 0
}
trap checkcommand DEBUG

好みに合わせてロジックを調整します。

(私は実際にこのアプローチが有用であることを期待していません-コマンドを破壊してコマンドを1つずつテストするために破壊する方法が多すぎる-それは質問に対する文字通りの答えを提供します)。

37
Charles Duffy

システムを完全に防弾する方法はありません。そして、「よろしいですか?」物事へのプロンプトは逆効果であり、「もちろん私は確信している」につながります。ひざまずく反応。

私が数年前に本から取り上げたトリックは、最初にls -R blah*を実行し、次にrm -fr blah*を実行することです。

最初にlsコマンドを実行し、次に ls -Rを削除し、rm -frに置き換えます。

最後の質問は、「情報があなたにとって価値がある場合、どこにバックアップがあるか」です。

46
killermist

たとえば、rm -rfの代わりにrmrfを使用するようにトレーニングできますか?

その場合、このbash関数は、コマンドを確認する前に実際に何が起こるかを確認する機会を提供します。

rmrf() { echo rm -rf "$@"; read -p "Proceed (y/N)? "; [ "${REPLY,,}" = y ] && rm -rf "$@"; }

この関数を永続的にするには、使用する各コンピューターの~/.bashrcファイルにこの行を追加します。

一般的なrmエイリアスとの比較

エイリアスを定義することは一般的です:

alias rm='rm -i'

これには2つの制限があります。

  1. このエイリアスに依存するようになると、マシン上またはそれを持たない環境にいるときにショックを受けることになります。対照的に、その関数を持たないマシンでrmrfを実行しようとすると、無害なcommand not foundが返されます。

  2. コマンドラインで指定する-fオプションは、エイリアスの-iオプションを上書きするため、このエイリアスは役に立ちません。

8
John1024

間違ったファイルを削除することが非常に重要な状況にある場合、私がやったことの1つはmkdir trashcanのようなゴミ箱フォルダーを作成することであり、その後スクリプトrmTrashcanrm -rf trashcan/*またはrm -rf *または同様のものが非常に慎重に記述され、数回チェックされています。

そうすれば、私がミスをした場合、ミスはmvコマンドではなくrmコマンドにあります。 lsを実行してexactlyを削除すると確信したら、rmTrashcanは実際に安全にダーティな作業を行います。

また、バックアップを削除しなければならない状況でも非常に便利でした。ゴミ箱に1か月分のバックアップをmvmv保持したい数個(月の1日、15日)をバックアップに戻し、rmTranshcan残り。同様のコマンドを実行するだけではrmを単独で実行するのは困難です。このように実行すると、バックアップをlsさせて、(単に削除するファイル)

6
Cort Ammon

2つのコマンド(lsrm)に煩わされる代わりに、findを使用するほうが簡単で簡単な方法だと思います。

find . -maxdepth 1 -name "string*" -delete

誤って"string *"と入力すると、string charsおよびstring lettersという名前のファイルが削除されます(とにかく必要なものです)。ただし、*のようなすべてのファイルがシェルはします。

また、-deleteを省略して、削除するファイルを確認し、上矢印キーを押して-deleteと入力するよりも、^ls -R^rm -rfと入力するよりも簡単です。

4
nanny

偶発的な末尾または先頭のワイルドカードからスマートに保護する簡単な方法はありますか?

あんまり。別の回答では、タスクを実行する前にプロンプ​​トを追加するカスタムコマンドを作成することが提案されています。ただし、このカスタムコマンドの問題は、作業中のシステムに意識的にインストールする必要があることです。そして、それがインストールされている場合でも、問題はyを押してタスクを完了するための反射神経が関与する可能性があることです。

これは、テキスト/コマンドラインレベルであっても、すべてユーザーインターフェイスの問題であることを意味します。してはいけないことからあなたを守るためにいくつのセーフティネットがあると思いますか?それはハサミのようなものです。もしあなたがなんらかの怠慢で、布や紙を切るつもりである間、滑って手を切ったなら、誰が悪いのですか?または、信号機や一時停止標識:ドライバーがそのような危険な行動をとった場合に何が起こるかについての深刻な認識以外に、運転手が信号を実行したり、交通標識を無視したりすることを止めるものはありません。

とはいえ、最良かつ現実的な解決策は、ユーザーとグループのシステム権限にあります。これは、ユーザーを自分自身から保護するための最良/唯一の実際のセーフティネットです。

自分だけがアクセスしているシステムで作業している場合、chmod 777すべてですが、それは合理的なシステムのセットアップ方法ではありません。代わりに、権限は755すべてのディレクトリおよび644すべての非実行可能ファイル。実行可能ファイルは755少なくとも、でも744他のユーザーにファイルの読み取りのみを許可し、実行は許可しない場合。

3
JakeGould

rmには、すべての削除の前に確認するための-iおよび-Iフラグがあります。以前は、一部のディストリビューションではデフォルトでオンになっています。これはひどい考えです。ユーザーに通常の操作のためにあまりにも多くの確認ダイアログを与えると、彼らは習慣的にそれらを確認し始めます。これは、「注意する」という要件(常に赤い旗)を、新しくて迷惑なダイアログにシフトするだけです。 「そうです。そうです。そうです。そうです。そうです。愚かなコンピュータがファイルを削除するだけですYESYESYESYESYES--CRAP I MEANT NO!NOOOOOOO!」これは「はい、でも私は意味がない」というダイアログの問題です。 この回答は視覚的な説明を提供します 確認ダイアログが間違ったタイミングで表示される理由。

あなたが説明する種類の間違いは スリップ 、「意図されたものではなかったアクションのパフォーマンス」です。ユーザーは通常、すぐに間違いを認識し、それを修正する方法を正確に知っています。残念ながら、Unixはユーザーに機会を与えません、rmはすぐにファイルを削除します。他のすべてのオペレーティングシステムでは、ゴミ箱を使用して削除を少なくともしばらくは元に戻せるようにすることで、この問題を解決しています。

Unixにはさまざまなゴミシステムがあります この回答は提案でいっぱいです

問題は、rmをエイリアスするか、rmをエイリアスしないかです。エイリアスエイリアスrmの利点...

  1. 代わりのrmを使用するのを忘れるようなことはできません。

エイリアスエイリアスrmの短所...

  1. あなたはそれを持たないシステムでそれに依存するようになるかもしれません。
  2. ディスクがほぼいっぱいになると、問題が発生する可能性があります。
  3. 定期的にゴミを空にするインフラストラクチャが必要です。
  4. プログラムで期待されるrmの動作に干渉しないように注意する必要があります。
  5. Rmを完全にエミュレートしない可能性があります。

最初の引数を過度に実行すると、vi(vim、viではなく)、csh(tcsh、cshではない)、および他の古くなったユーティリティが広く利用できるようになるため、それらを使用することになります。それでも、環境をカスタマイズしすぎる危険があります。私はユーティリティを持ち歩いて、それをできるだけ簡単にすることを好みます。 YMMV。

2つと3つは技術的な問題です。 tmpreaper と同様に、ゴミのサイズをチェックして定期的にクリーンアップする賢いリーパージョブで解決できます。これはcronジョブにすることも、より巧妙なバージョンで多くのデスクトップLinuxディストリビューションで利用できるさまざまなファイルシステムイベントインフラストラクチャを利用することもできます。これは単純ではなく、効率的に行うのはさらに困難です。自分でシステムを作成するよりも、既存のシステムを見つける方が良いでしょう。

4番目は、新しいrmをシェルエイリアスalias rm='trash'にすることで処理でき、プログラムには影響しません。

5番目は、読者が解決しなければならない問題です。 rmには多くのスイッチがありません。

2
Schwern

最後のコマンドトリックの!$ =最後の引数についてみんなに教えます:

% ls job[XYZ].*
jobX.out1
jobX.out2
[rest of the matches]

% rm !$

これにより、ワイルドカードの展開を検査し、*の前にスペースを挿入することなく、まったく同じグロブパターンを使用できます。

また、破壊的な可能性のあるコマンドラインでは、グロビングワイルドカードパターンをカットアンドペーストしないでください。私自身の手でそれが問題になっているので:)

私の研究室の技術者が先週このミスを犯しました(3か月の作業)-はい、バックアップ(1日遅れ)がありました。

2
kael

最初のrmコマンドを-fフラグなしで構成し、代わりに-iを使用して、rmが削除対象のファイルごとにプロンプ​​トを表示するようにします。小さな再帰的な削除の場合は、 y キー、コマンドが正しく入力されたことを確認したら。大量の削除の場合は、操作を中止し、コマンドライン履歴を使用して-i-fに慎重に変更できます。

2
Nevin Williams

誰もが「もっと注意してください」、「エイリアス/確認プロンプトを作成しないでください」と言っているようです。

クール、そしてすべて。つまり、rm(またはrmrfのエイリアスを作成して、実際のコマンドを簡単に入力できるため)のエイリアスを作成する必要はないと思います。

しかし、なぜエイリアス/スクリプトを作成して、それをremoveと呼んで、1つの引数(例:$ 1)だけをフィードできないのでしょうか。ワイルドカードは$ 2にする必要があります。これは、不注意なスペース(amiright?)が原因であり、スクリプト/ラッパー/エイリアスに2番目のスペースが渡されないためです。はい、一度に削除できるのは(ワイルドカードを使用して)1セットだけですが、それが支払う代金です。

何か素敵なものを書いている場合は、削除する予定のファイルとディレクトリの数、削除するものの合計サイズを確認し、確認を求めますが、フローを妨げる可能性があります。多分それをremoveのフラグオプションにする? (-私)。また、$ 1をチェックして、それがjust単一のワイルドカードであるかどうかを確認し、確認を求め、実際にどのディレクトリにいるかをリストすることもできます。


余談ですが、そこには多くのrm置換があります。多くのユーザーがUIデスクトップのゴミ箱に準拠しようとしています。それらのいくつかは調べる価値があるかもしれません。

0
user3082

非常に簡単なトリックは、最後に-rfを付けることです:rm whatever* -rf
これにより、エラー率が大幅に減少します。*の後に文字をさらに入力するため、タイプミスを表示する時間が増えるためです。
これですべてが解決されるわけではありません。単純な日常のトリック。

0
Gregory MOUSSAT