ある日zshの履歴が消えた悲しみからいくつか課題感を持っていた。
- 巨大な1ファイルにどんどん書いていくので、壊れたときの影響が大きい
- 追記方式なので、複数の端末で共有するためGitやDropboxなどに入れるとコンフリクトしやすい
- 履歴から取り出すときにどのディレクトリで実行したコマンドなのかわからない
シェル履歴をファイルに書いて終わりという暮らしは数十年変わっていない。
履歴はクラウドサーバーに保存して、補完したいときにAPI経由で問い合わせるというアーキテクチャが良いと思ったので、作ってみた。
github.com
コマンドの実行時
- zshのフックを使って、コマンドの実行時に、実行したコマンドと$pwdをAPIにPOSTする
- Cloud Functionsが立っていて、送られたコマンドをCloud Datastoreに保存する
Cloud FunctionsはGoogle製のAWS Lambdaみたいなやつで、Cloud DatastoreはGoogle製のAmazon DynamoDBみたいなやつ。
普通に暮らしてると、こんなかんじにDatastoreで履歴を見れる。見えるとまずい情報があったらポチポチやって消せる。
履歴の補完
- $pwdを指定してAPIをGETする
- そのディレクトリでのコマンドに絞り込んでJSONを返す
- pecoで選択して実行する
こんな感じのJSONが出てくる。pwdを保存してるのが新規性がある。
[ { "timestamp": "2018-11-16T07:09:28.066Z", "command": "curl --silent \"$POST_SHELL_HISTORY_APIROOT/accept?apikey=${POST_SHELL_HISTORY_APIKEY}&pwd=${PWD}\" | jq . | less", "pwd": "/Users/hitode909/co/github.com/hitode909/post-shell-history" }, { "timestamp": "2018-11-16T07:09:22.482Z", "command": "curl --silent \"$POST_SHELL_HISTORY_APIROOT/accept?apikey=${POST_SHELL_HISTORY_APIKEY}&pwd=${PWD}\"", "pwd": "/Users/hitode909/co/github.com/hitode909/post-shell-history" }, { "command": "make deploy", "pwd": "/Users/hitode909/co/github.com/hitode909/post-shell-history", "timestamp": "2018-11-16T02:45:08.860Z" }, ]
やってみたところ、候補をディレクトリで絞り込めるのがたいへん便利。こっちのプロジェクトはnpm run buildだけどこっちではmake js、とかこれまでは覚えておくしかなかったのが、履歴から選べば正解が出る。
初めて触るディレクトリなどのとき用に、ディレクトリを指定せず全履歴から選ぶモードも作った。
これからデータが増えると事情が変わってきそうだけど、実行時間も気にならず動いているので、もともとあったCtrl-rでファイルからヒストリを絞り込むのを消して、クラウドから引っ張ってくる版だけで暮らしている。
困り
作り始めたところなのでいろいろ困り事はある。
- オフラインで動かない
- バッファリングしてないのでオフラインでの作業はロストしてしまう。バッファリングする仕組みを作ると良いけどやってない
- 作りが荒い
- precmdで
curl &
してるだけなので[1] 87143
や[1] + done curl --silent --data-urlencode "command=${command}" --data-urlencode >&
というのが1コマンド打つたびに出てくる
- precmdで
- 認証をちゃんとやってない
- APIキーでの認証を手作りしたけどGoogleのアカウントと連携してOAuthで使い始められるとよさそう。いまは1人1個GCPのプロジェクトを作るということにしている。
手元のファイルを大切にする時代は終わったと信じて、未来に進んでいきたい。
関連
- 突然シェルのhistoryが消えてめっちゃつらい - hitode909の日記
- ヒストリが消えたときの日記
- GitHub - hitode909/post-shell-history-to-gcloud: WIP
- 今回作ったやつ