追記: Bashにも対応しました
皆さんもpeco/percol/fzf/anyfinderなどのフィルタリングツールを便利に使っていると思います。
ちなみに私はpeco派です。
コマンド実行間違い
ところで、*sh_historyを使ったコマンド補完をpecoにまかせていて ( こういうの )、「コマンド実行間違い」をしてしまうことありませんか?
例えば、
bundle exec cap staging deployのつもりがbundle exec cap production deployを選択して本番環境へデプロイしまったりdocker container start xxxのつもりがdocker container stop $(docker container ls -aq)を選択して全てのコンテナをストップさせてしまったり
pecoを経由した「フィルタリングして実行」があまりに便利なので、ついつい「フィルタリング -> 選択」をカジュアルに実施してしまい、結果、コマンド実行間違いが多くなってしまいました。
ちなみに、最近私がやらかしたコマンド実行間違いは、Roadworkerのテストを AWS_PROFILE=my-awstest bundle exec rake で実行するつもりが、AWS_PROFILE=k1low bundle exec rake で実行してしまい、プライベートのRoute53のHostedZone設定を全て消してしまったことです ( これ で簡単にテスト環境をつくれるようになったから。。。 )。
いつか、もっと危険なコマンド実行間違いをやらかしそうです。
ExeCopで危険なコマンド実行間違いを防ぐ
というわけで、コマンド実行間違いを防ぐためにExeCopという名前でzshスクリプトを書いてみました。
ExeCopは、.execop ファイルを設置しておくことで、そのディレクトリ以下で実行するコマンドを監視してくれます。
そして .execop ファイルに書いてある設定に沿ってコマンドをキャンセルしたり yes/no の確認フェーズをはさんだりします。

インストール
execop.zsh を任意の場所にダウンロードし、 .zshrc に以下のように記述します。
. /path/to/execop.zsh
Bashの場合は、execop.bash を任意の場所にダウンロードし、 .bashrc に以下のように記述します。
. /path/to/execop.bash
.execop ファイルの設置
.execop ファイルは例えば以下のように書きます。
deny when command_match destroy confirm when command_match rm deny when command_eq rm -rf / confirm when env_eq AWS_PROFILE=production
上記の設定だと、
- コマンドに
destroyという文字列が入っていた時、コマンド実行をキャンセルする - コマンドに
rmという文字列が入っていた時、yes/noの確認フェーズをはさむ - コマンドが
rm -rf /だった時、コマンド実行をキャンセルする - 環境環境
AWS_PROFILEがproductionだった時、yes/noの確認フェーズをはさむ
という監視がはいるようになります。
例えば、TerraformのファイルがあるディレクトリでAWS_PROFILEに制限をかけたり、Capistranoのデプロイディレクトリでデプロイコマンドに確認フェーズを差し込むなどすると良さそうです。
.execop ファイルの監視設定のフォーマットは以下のような感じです。
[action] when [matcher] [command or environment value]
actionは deny か confirm の2つ。
matcherは今のところ command_match command_not_match command_eq command_not_eq env_eq env_not_eq を実装しています。
懸念点
ExeCopを導入するとコマンド実行のたびに監視処理が走ります( preexec )。
若干挙動が遅くなるかもですが、危険なコマンド実行間違いをするよりはマシなのでこのまま運用してみようと思います。
というわけで
危険なコマンド実行間違いにビクビクしている方は、 自己責任で ご利用ください。
ちなみに、皆さんはどのようにしてコマンド実行間違いを防いでいるんでしょうか。