docker psコマンドで出力される情報をカスタマイズする( –format オプション )

2023-03-27Docker

はじめに

docker ps コマンドで現在稼働中の Docker コンテナを確認できます。

デフォルトでは以下のような情報が出力されます。

$ docker ps
CONTAINER ID   IMAGE                    COMMAND       CREATED          STATUS          PORTS     NAMES
05d7ee2a983c   genzouw/ubuntu-sandbox   "/bin/bash"   1 second ago     Up 1 second               adoring_bassi
78c24e86b192   genzouw/ubuntu-sandbox   "/bin/bash"   34 seconds ago   Up 33 seconds             tender_carson

ここでは 2 つのコンテナが実行されています。

CONTAINER IDIMAGE の情報を取り出して、パイプで別の処理に引き渡したい(例えば、実行中プロセスをすべて停止したい)場合は、 cutawk を使って処理する方法が考えられます。

# 2行目以降を出力し、1列目のみを取り出す
$ docker ps | tail -n +2 | cut -d ' ' -f 1
6965cb418c29
7ff433dc6fb0

# 2行目以降を出力し、2列目のみを取り出す
$ docker ps | tail -n +2 | awk '{ print $2 }'
genzouw/ubuntu-sandbox
genzouw/ubuntu-sandbox

ヘッダーの除去するための tail や、 任意の列だけを取り出すための cutawk を使わずに --format オプションを使用する方法があります。また--format オプションには少し変わった使い方もあります。

検証環境

$ uname -moi
arm64 unknown Darwin

$ docker --version
Docker version 20.10.21, build baeda1f

--format オプションを使って出力形式を制御する

docker ps コマンドを --format オプション付きで実行することで、任意の情報のみを出力するように制御できます。

--format オプションは引数指定が必須であり、引数は Go 言語テンプレート に従った記法で指定します。

Go 言語テンプレートについては こちら に記載がありました。

PHP の Smarty や Java の Velocity のようなテンプレートエンジンには変数の埋め込みが可能ですが、 Go 言語テンプレートでは {{.VARIABLE}} の形式で変数を埋め込めます。

コンテナ ID だけを出力

--foramt を使って、コンテナ ID だけを出力してみます。

$ docker ps --format '{{ .ID }}'
6965cb418c29
7ff433dc6fb0

パイプで別のコマンドに情報を引き渡しやすく、ヘッダー情報が表示されません。

docker コマンドでは、コンテナ ID を表す組み込み変数は ID です。
Go 言語テンプレートの形式に乗っ取り、 {{ .ID }} の形式で埋め込みます。

テンプレートエンジンの仕組みを利用しているので、前後の文字列リテラルを埋め込むことも可能です。

$ docker ps --format '*** {{ .ID }} ***'
*** 6965cb418c29 ***
*** 7ff433dc6fb0 ***

コンテナ ID とイメージ ID を出力

コンテナ ID とイメージ ID を出力してみます。

$ docker ps --format 'コンテナID は {{ .ID }} で、 イメージID は {{ .Image }} です'
コンテナID は 6965cb418c29 で、 イメージID は genzouw/ubuntu-sandbox です
コンテナID は 7ff433dc6fb0 で、 イメージID は genzouw/ubuntu-sandbox です

コンテナ名 とイメージ ID をヘッダー付きで出力

ヘッダーも出力したい場合には、 --format の前に table というキーワードを記述します。

カラムの間には任意の文字列を入れて区切りましょう。

# タブ区切り
$ docker ps --format 'table {{ .Names }}\t{{ .Image }}'
CONTAINER ID   IMAGE
6965cb418c29   genzouw/ubuntu-sandbox
7ff433dc6fb0   genzouw/ubuntu-sandbox

# カンマ区切り
$ docker ps --format 'table {{ .Names }},{{ .Image }}'
NAMES,IMAGE
charming_cannon,genzouw/ubuntu-sandbox
relaxed_goldberg,genzouw/ubuntu-sandbox

# (おまけ) 文字列リテラルを埋め込んだ場合のヘッダー
$ docker ps --format 'table コンテナID は {{ .ID }}\tイメージID は {{ .Image }} です'
コンテナID は CONTAINER ID   イメージID は IMAGE です
コンテナID は 6965cb418c29   イメージID は genzouw/ubuntu-sandbox です
コンテナID は 7ff433dc6fb0   イメージID は genzouw/ubuntu-sandbox です

if 文を使う

go 言語テンプレートの仕様に則っているので、 if 文も使用できます。

# trueの時
$ docker ps --format '{{if true}}{{ .ID }}{{else}}hello{{end}}'
6965cb418c29
7ff433dc6fb0

# falseの時
$ docker ps --format '{{if false}}{{ .ID }}{{else}}hello{{end}}'
hello
hello

--format オプション内で使える組み込み変数

ここまでの例では、 --format オプション内で {{ .ID }}{{ .Image }}{{ .Names }} という変数を使いました。

他にも利用できる変数があります。

利用可能な変数の一覧は以下のページから確認できます。

JSON フォーマットで出力

すべての情報を JSON 形式で出力することもできます。
--format で利用可能な変数を確認するためにも利用できます。

見にくいので、 jq コマンドをセットで使うことをおすすめします。

# みにくい
$ docker ps --format '{{json .}}'
{"Command":"\"/bin/bash\"","CreatedAt":"2023-02-07 08:50:06 +0900 JST","ID":"6965cb418c29","Image":"genzouw/ubuntu-sandbox","Labels":"desktop.docker.io/binds/0/Target=/workdir,maintainer=genzouw \u003cgenzouw@gmail.com\u003e,desktop.docker.io/binds/0/Source=/Users/genzouw/work,desktop.docker.io/binds/0/SourceKind=hostFile","LocalVolumes":"0","Mounts":"/host_mnt/User…","Names":"charming_cannon","Networks":"bridge","Ports":"","RunningFor":"48 minutes ago","Size":"0B (virtual 1.44GB)","State":"running","Status":"Up 48 minutes"}
{"Command":"\"/bin/bash\"","CreatedAt":"2023-02-07 08:50:03 +0900 JST","ID":"7ff433dc6fb0","Image":"genzouw/ubuntu-sandbox","Labels":"desktop.docker.io/binds/0/Source=/Users/genzouw/work,desktop.docker.io/binds/0/SourceKind=hostFile,desktop.docker.io/binds/0/Target=/workdir,maintainer=genzouw \u003cgenzouw@gmail.com\u003e","LocalVolumes":"0","Mounts":"/host_mnt/User…","Names":"relaxed_goldberg","Networks":"bridge","Ports":"","RunningFor":"48 minutes ago","Size":"0B (virtual 1.44GB)","State":"running","Status":"Up 48 minutes"}

# jq を通すと見やすい
$ docker ps --format '{{json .}}' | jq .
{
  "Command": "\"/bin/bash\"",
  "CreatedAt": "2023-02-07 08:50:06 +0900 JST",
  "ID": "6965cb418c29",
  "Image": "genzouw/ubuntu-sandbox",
  "Labels": "desktop.docker.io/binds/0/Source=/Users/genzouw/work,desktop.docker.io/binds/0/SourceKind=hostFile,desktop.docker.io/binds/0/Target=/workdir,maintainer=genzouw <genzouw@gmail.com>",
  "LocalVolumes": "0",
  "Mounts": "/host_mnt/User…",
  "Names": "charming_cannon",
  "Networks": "bridge",
  "Ports": "",
  "RunningFor": "48 minutes ago",
  "Size": "0B (virtual 1.44GB)",
  "State": "running",
  "Status": "Up 48 minutes"
}
{
  "Command": "\"/bin/bash\"",
  "CreatedAt": "2023-02-07 08:50:03 +0900 JST",
  "ID": "7ff433dc6fb0",
  "Image": "genzouw/ubuntu-sandbox",
  "Labels": "maintainer=genzouw <genzouw@gmail.com>,desktop.docker.io/binds/0/Source=/Users/genzouw/work,desktop.docker.io/binds/0/SourceKind=hostFile,desktop.docker.io/binds/0/Target=/workdir",
  "LocalVolumes": "0",
  "Mounts": "/host_mnt/User…",
  "Names": "relaxed_goldberg",
  "Networks": "bridge",
  "Ports": "",
  "RunningFor": "48 minutes ago",
  "Size": "0B (virtual 1.44GB)",
  "State": "running",
  "Status": "Up 48 minutes"
}

docker inspect コマンドでも使える

--format オプションは docker ps 以外でも利用できます。
docker inspect コマンドでも同様の気泡となっています。

# --format オプション無しで実行した場合
$ docker inspect 6965cb418c29  | head
[
    {
        "Id": "6965cb418c297ec57a4a6259c268d8be0cbbbf88986bb9bae34bca8d136fb18d",
        "Created": "2023-02-06T23:50:06.161622048Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,

# --format オプション有り
$ docker inspect 6965cb418c29 --format '{{ .ID }} は {{ .State.Status }} です'
6965cb418c297ec57a4a6259c268d8be0cbbbf88986bb9bae34bca8d136fb18d は running です

ひとこと

便利ですが、ID だけほしいときは調べるのが面倒で docker ps -a | tail -n +2 | awk '{ print $1 }' を実行したほうが早いです。

2023-03-27Docker