0

数週間前、上級チームのメンバーが重要なOracleデータベースファイル(.dbf)を予期せず削除しました。幸い、数日前に保存したバックアップファイルを使用してシステムを復元することができました。

その状況を見てrm、プロンプトでコマンドを入力するときに少なくとも二重の確認を行うソリューションを実装することにしました。(以上をチェックしますrm -i

私たちがデフォルトでエイリアシングrm -iをしているとしても、超高速のキーボード奏者は通常、私を含めてそのメンバーのように間違いを犯します。

最初に、(エイリアスを使用して)基本的なrmコマンドを特定のbashスクリプトファイルに置き換えました。このスクリプトファイルは、ターゲットがOracleデータベースのパスまたはファイルに関連しているかどうかを何度も印刷して確認します。簡単に言えば、スクリプトはrmを操作する前にフィルターとして動作します。oracleに関連していない場合、rmは通常どおり動作します。

実装中は、1つの懸念事項を除いて、ユーザープロンプト環境のみを期待していたため、ほとんどの機能が適切に動作していると思いました。

rmコマンドが他のスクリプト(提供されたオラクル、オラクルパスを変更する他のベンダー、インストーラーなど)またはプログラム(システムコールを使用)内で呼び出された場合。

  1. その状況をどのように区別できますか?上記で提供されたスクリプトが変更されたrmに適合した場合、その実行はそれ以上先に進みません。

  2. もっと洗練された方法はありますか?

読者のほとんどは私の怠惰な説明を理解できると思います。上からの景色がよくわからない場合はお知らせください。もっと詳しく説明します。

4

4 に答える 4

3

私たちはで読んでいman bashます:

シェルが対話型でない場合、expand_aliases シェル オプションが shopt を使用して設定されていない限り、エイリアスは展開されません。

次に、シェルスクリプトを呼び出すために使用aliasするとrm、他のスクリプトはデフォルトでそれを使用しません。それがあなたの望むものなら、あなたはすでに安全です。

問題は、自分のバージョンの rm をスクリプトによって呼び出して、それが発生したときにスマートに何かを実行したい場合です。前者にはエイリアスだけでは不十分です。rmを明示的に呼び出すプログラムには、どこかに置く$PATHだけでは十分ではありません/bin/rm。また、シェル スクリプトではないプログラムの場合、unlinkシステム コールはsystem("rm ...").

「安全な rm」全体が有用であるためには、対話的に呼び出された場合でもプロンプトを回避する必要があると思います。すべてのユーザーは、それに「はい」と言う習慣を身につけますが、それを回避する方法は知られていません。ファイルを削除する代わりにごみ箱に移動し、損傷を簡単に元に戻せるようにすることがうまくいく可能性があります (私が思い出すように、これにはすぐに使用できるソリューションがありました)。

于 2013-01-21T13:10:49.327 に答える
1

答えはaliasマンページにあります:

          Note  aliases  are  not  expanded  by default in non-interactive
          shell, and it can be enabled by setting the expand_aliases shell
          option using shopt.

自分で確認してくださいman alias;)

とにかく、私はあなたが選んだのと同じ方法でやります

于 2013-01-21T13:03:19.973 に答える
0

状況を区別するには:env変数say、を作成できます。これは、sayAPPLに設定されますexport APPL="DATABASE。カスタマイズしたスクリプトで、 is (データベース関連のスクリプトを示す)のrm場合にのみダブルチェックを実行します。それ以外の場合は、呼び出しが他のスクリプトからのものであることを意味します。APPLDATABASErm

于 2013-01-21T13:15:33.507 に答える
0

を使用している場合は、シェル関数bashエクスポートして、スクリプトでも使用できるようにすることができます。

#!/usr/bin/env bash

# Define a replacement for `rm` and export it. 
rm() { echo "PSYCH."; }; export -f rm

シェル関数は組み込みおよび外部ユーティリティよりも優先されるためrm、スクリプトを使用するだけでも関数が呼び出され/bin/rm ...ますcommand rm ...

上記を ( の実際の実装とともにrm()) 各ユーザーの~/.bashrcファイルまたはシステム全体の bash プロファイルに配置します。残念ながら、その場所は標準化されていません (例: Ubuntu: /etc/bash.bashrc; Fedora /etc/bashrc)

于 2014-07-06T18:36:13.243 に答える