いかに危険なコマンド実行間違いを防ぐか。そのためにExeCopを書いてみた
追記: 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
)。
若干挙動が遅くなるかもですが、危険なコマンド実行間違いをするよりはマシなのでこのまま運用してみようと思います。
というわけで
危険なコマンド実行間違いにビクビクしている方は、 自己責任で ご利用ください。
ちなみに、皆さんはどのようにしてコマンド実行間違いを防いでいるんでしょうか。