
私は私が犯すことができる間違いについてシェルが私に警告したいと思います。
NETcmd2
でコマンドが実行されないようにする方法cmd1
たとえば、
$ tar tf file.tar
$ rm !$
ここでは、コンテンツを抽出するのではなく、ファイルを一覧表示したことを忘れていました。
私は現在のコマンドだけでなく、以前のコマンドの名前と戻り値に基づいて選択する一般的な解決策を探しています。
答え1
shopt -s histverify
Bashでは、履歴が1段階に拡張され実行されるのを防ぐための項目を設定できます。ここで最初に押すと上記の内容が展開$ rm !$
され、[再実行]をクリックする前に確認または編集できます。より一般的な解決策は次のとおりです。$ rm file.tar
EnterEnter
「私が望むようにしてください」領土、あなたの意図を推測するプログラムが必要です。
答え2
あなたは多くの一般的な答えを求めていますが、ある程度は比較的簡単です。
ただし、bash
この問題を解決するのに役立つ一般的なメカニズムが複数あります。プロンプトで何かを実行した後に実行する変数PROMPT_COMMANDを設定できます。
$ PROMPT_COMMAND='echo BOFH says hi!'
BOFH says hi!
$ man man
BOFH says hi!
$
これを使用して、最後に入力したコマンドを保存してから再読み込みして、後で使用するためにメモリに保存できます(この場合、履歴拡張は機能しません)。
$ PROMPT_COMMAND='history -a; tail -n1 ~/.bash_history'
PROMPT_COMMAND='history -a; tail -n1 ~/.bash_history'
$ wc < test.sh | grep .
5 11 63
wc < test.sh | grep .
これで論理部分が出ます。これは完全にあなた次第です。質問の例をブロックするために、非常に単純なロジックを試してみましょう。覚えておくべきことは、bash機能がまだ機能しているので、すべてを1行、単一の変数に入れる必要がないことです。
$ # define the logic check
$ checkSanity() { grep -q "tar *[tf][[:alpha:]]*[tf] " <<< "$@" && echo "be careful, don't delete this"; }
checkSanity() { grep -q "tar *[tf][[:alpha:]]*[tf] " <<< "$@" && echo "be careful, don't delete this"; }
$ # feed it the last command
$ PROMPT_COMMAND='history -a; last=$(tail -n1 ~/.bash_history); checkSanity "$last"'
$ # simple test
$ tar tf test.sh 2>/dev/null
be careful, don't delete this
$ tar xf test.sh 2>/dev/null
$
もちろん、このアプローチはPEBKACを防ぐのに役立ちますが(特にsleep 3
最後に追加する場合)、次のコマンド自体は中断されません。
もしそうなら本物必要なものは、事前に実行されるDEBUG
信号(たとえば)をキャプチャします。trap 'echo "I am not deterministic, haha"' DEBUG
出力/操作が倍増するため、これら2つの方法を組み合わせるときは注意してください。
$ df
/.../
$ trap 'tail -n1 ~/.bash_history' DEBUG
df
df
trap 'tail -n1 ~/.bash_history' DEBUG
trap 'tail -n1 ~/.bash_history' DEBUG
トラップこのコマンドを中断するには、そのトラップを有効にする必要がありますextdebug
(shopt -s extdebug
)。また、履歴を保存し続ける必要はありませんが、$BASH_COMMAND
今後のコマンドを確認することもできます。その後、ロジックチェッカーが誤った場合を検出した場合は1を返し、そうでない場合は0を返すことを確認します。
extdebug
If set, behavior intended for use by debuggers is enabled:
/.../
2. If the command run by the DEBUG trap returns a non-zero value, the next
command is skipped and not executed.
$ checkSanity() { if grep -q "tar *[tf][[:alpha:]]*[tf] " <<< "$1"; then echo "be careful, don't delete this"; return 1; fi; }
$ trap 'checkSanity "$BASH_COMMAND"' DEBUG
$ # simple test
$ tar tf test.sh 2>/dev/null
be careful, don't delete this
$ tar xf test.sh 2>/dev/null
$
答え3
この場合、コマンドのエラー警告によって利点が得られますrm
。
シェル初期化スクリプト(bash
、so仮定)またはエイリアスを使用~/.bashrc
できます。rm
-i
-I
alias rm="rm -i"
~からman 1 rm
-i prompt before every removal
-I prompt once before removing more than three files, or when
removing recursively. Less intrusive than -i, while still
giving protection against most mistakes
より一般的な質問は「自分自身からシステムをどのように保護しますか?」です。前に議論した。要するに、やっていることに注意を払う、必要な場合にのみroot
コマンドを実行します。
答え4
あなたの特定の状況に応じて、次のようにします。
tar tf file.tar
if [ -f file ]; then # Assuming you meant to extract a file
rm -f file.tar
else
echo "file is missing. Command failed."
fi
エラーを確認し、最初のコマンドが成功した場合にのみ、次のコマンドを実行したい場合
some_command && another_command
ただし、特定の場合には、目的の操作を実行しなくてもエラーが発生しないため、2番目のコマンドは引き続き実行されます。