コンテナに入るのに docker ps してから docker start して docker exec するのめんどくさいから一度にできるコマンド作った
結論
作った。Goで。 github.com
経緯
パソコン起動してから、dockerのコンテナに入るのにコマンドをいくつも叩かないといけないのがめんどくさかったから。
叩くコマンドは以下の3つ
* docker ps -a
* docker start <コンテナ名>
* docker exec -it -e <デフォルト環境変数> <コンテナ名> bash
コマンドの内容としては、単純で docker ps -a --format "{{.Name}}"
で出力されたコンテナ名を cho
で選択して、それを docker start
に渡して実行した後、docker exec
をコンテナ名とともに起動しているだけ。
cho に関しては、以下のリンクを参照。パイプで渡された文字列に対して行単位で選択ができるコマンド。今回作ったコマンドを実行するには必要なので、別途 go get https://github.com/mattn/cho
でインストールしておく必要がある。
mattn.kaoriya.net
知見
docker ps の書式指定
docker ps
に --format
というのがあり、表示するフォーマットをGoのtemplate書式で指定できる。
docker ps --format "{{.Name}}" とすれば、コンテナ名のみ表示され
docker ps --format "table {{.ID}}\t{{.Labels}}"とすれば、ヘッダ行を追加した状態で
IDと
Label`が表示されるので便利。
go-pipeline の Output で返される文字列
docker ps
と cho
を繋ぐために、今回は go-pipeline
(GitHub - mattn/go-pipeline) を使用したが、返される文字列をそのまま exec.Command() の引数として使うとエラーとなる。理由としては文字列の最後に改行文字が入っており、コンテナ名が存在しない。となるからだ。解決方法としては、最後の1バイトを取り除いた部分文字列を渡すことで解決した。
docker exec が動かない
上記問題を解決したうえで docker exec
が実行時にエラーとなっていた。原因は exec.Command で作成した Cmd 構造体の Stdin と Stdout にちゃんと標準入力と標準出力をセットしていなかったことが原因だった。nil のままだと NULLデバイス(os.DevNull)にアクセスするようだ。(https://golang.org/pkg/os/exec/#Cmd)