Dockerでカスタムsubcommandをあれする

Gitでは git-foo のような名前のスクリプトファイルを PATH の通っている位置に置いておくと、 git foo とするだけで呼び出せる便利な仕組みがあります。

本記事の趣旨はDockerでもそんな感じのことをしたいよね。というあれです。

実装

で、以下のような関数を .zshrc なりに書いて置くとGitのような感じでsubcommandを探索してくれます。

docker() {
    if [ "$#" -eq 0 ] || ! command -v "docker-$1" > /dev/null; then
        command docker "$@"
    elif (( ${+aliases[docker-$1]} )); then
        eval "${aliases[docker-$1]} ${(q)@:2}"
    else
        "docker-$1" "${@:2}"
    fi
}

この関数 docker を用いて docker foo のようにサブコマンドを呼び出した場合、

  • docker-foo」のようなコマンドやエイリアスが存在していない場合は生のdocker コマンドに引数を渡す
  • docker-foo というエイリアスが存在していれば docker-foo に残りの引数を渡す1
  • docker-foo というスクリプトか関数が存在していれば docker-foo に残りの引数を渡す

というような感じであれしてくれます。

自分は以下のようなエイリアスを使っています。

# docker run のエイリアス 
alias docker-ri='command docker run -it'
alias docker-rrm='command docker run --rm'
alias docker-rrmi='command docker run --rm -it'

# exitedなプロセスを全部 rm する
docker-clean() {
    command docker ps -aqf status=exited | xargs -r docker rm --
}
# タグ付けされていないイメージを全部 rmi する
docker-cleani() {
    command docker images -qf dangling=true | xargs -r docker rmi --
}

# 引数なしで docker rm すると削除するプロセスを fzf で選択できる
docker-rm() {
    if [ "$#" -eq 0 ]; then
        command docker ps -a | fzf --exit-0 --multi --header-lines=1 | awk '{ print $1 }' | xargs -r docker rm --
    else
        command docker rm "$@"
    fi
}

# 引数なしで docker rmi すると削除するイメージを fzf で選択できる
docker-rmi() {
    if [ "$#" -eq 0 ]; then
        command docker images | fzf --exit-0 --multi --header-lines=1 | awk '{ print $3 }' | xargs -r docker rmi --
    else
        command docker rmi "$@"
    fi
}

余談

それでいいのか?


  1. git はシェルエイリアスの探索はしてくれませんが、git config alias.foo の代替みたいな気持ちです