Docker 的 inspect 命令用于查看容器、镜像、网络、卷等 Docker 对象的低级详细信息。默认输出为 JSON 格式,但通过 --format(或 -f)选项,可以使用 Go 模板(text/template)自定义输出格式。这使得我们能够精确提取所需字段、格式化输出,甚至进行条件判断和循环处理。
Go 模板的核心语法是 {``{ }},其中可以放置变量、函数、控制结构等。Docker 在标准 Go 模板基础上添加了一些自定义函数(如 json、join、split 等),以便更好地处理 JSON 数据。
1. 什么是模板?
模板的概念源于 MVC(Model-View-Controller)框架:Model 处理数据,View 负责展示,Controller 协调两者。
在 Docker 中,inspect 返回的 JSON 数据相当于 Model,而 --format 允许我们定义 View:将静态文本与动态数据结合,生成自定义输出。
例如,容器列表的表头(如 "CONTAINER ID"、"NAMES")是固定的,而具体值是动态的。通过模板,我们可以复用静态部分,只提取需要的动态字段,提高效率和可读性。
参考官方文档:Go 的 text/template 包提供了详细语法,Docker 在此基础上扩展。
2. Go 模板基本语法
-
注释 :
{``{/* 注释内容 */}}bashdocker network inspect --format='{{/* 查看容器的默认网关 */}}{{range .IPAM.Config}}{{.Gateway}}{{end}}' <network_id> -
当前对象 :
.(点号)表示当前上下文对象,类似于 Java 中的this。bashdocker inspect --format '{{.State.Status}}' <container_id> # 输出 running/exited 等
3. 变量
3.1 系统变量(. 和级联)
-
使用
.Field访问字段,支持级联:.Parent.Child.Grandchild -
如果字段名包含点号(
.)或以数字开头,不能直接用.Field,会解析错误。bash# 错误示例 docker inspect --format '{{.Options.com.docker.network.driver.mtu}}' bridge # 正确:使用 index 函数 docker inspect --format '{{index .Options "com.docker.network.bridge.name"}}' bridge
示例:
bash
docker inspect -f '{{.Id}}' <container> # 完整 ID
docker inspect -f '{{.State.Status}}' <container> # 状态:running
docker inspect -f '{{"status:"}}{{.State.Status}}' <container> # status:running
3.2 自定义变量
使用 $var := value 定义变量,可在后续使用。
bash
docker inspect --format '已绑定端口列表:{{println}}{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{println}}{{end}}' <container>
输出示例:
已绑定端口列表:
80/tcp -> 32770
8081/tcp -> 8081
4. 遍历(range)
用于迭代数组、切片、map 或 channel。
bash
{{range pipeline}} ... {{.}} {{end}}
{{range pipeline}} ... {{else}} ... {{end}} # 无数据时执行 else
示例:
bash
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container> # 输出所有 IP
docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{end}}' <container>
# 输出:9090/tcp -> 9090
5. index 函数
用于访问 map、slice、array 或 string 的元素(索引从 0 开始)。
bash
docker inspect --format='{{(index (index .NetworkSettings.Ports "9090/tcp") 0).HostPort}}' <container>
6. 判断(if-else)
bash
{{if pipeline}} ... {{end}}
{{if pipeline}} ... {{else}} ... {{end}}
{{if pipeline}} ... {{else if pipeline}} ... {{end}}
内置逻辑函数:
not:否定and/or:逻辑与/或(or返回第一个非空值)- 比较:
eq(等于,支持多参数)、ne、lt、le、gt、ge
示例:
bash
docker inspect --format '{{if not .State.Restarting}}容器没有配置重启策略{{end}}' <container>
docker inspect --format '{{if ne 0 .State.ExitCode}}{{.Name}}{{else}}该容器还在运行{{end}}' $(docker ps -aq)
7. 打印函数
print:默认输出,多个参数间加空格println:类似 print,但末尾换行(或直接{``{println}}换行)printf:格式化输出,支持%d、%s等占位符
bash
docker inspect --format '{{printf "Pid:%d ExitCode:%d" .State.Pid .State.ExitCode}}' <container>
# 输出:Pid:24039 ExitCode:0
8. 管道(pipeline)和 Docker 扩展函数
管道类似于 shell 的 |,可链式调用函数。
Docker 扩展函数(官方文档:https://docs.docker.com/config/formatting/):
-
json:将结构体输出为 JSON(默认是 Go 风格 dump)bashdocker inspect --format '{{json .State}}' <container> | jq -
join:连接切片元素bashdocker inspect --format '{{join .Config.Env "\n"}}' <container> -
split:拆分字符串 -
upper/lower/title:大小写转换 -
truncate:截断字符串 -
pad:填充空格
其他命令如 docker ps 支持 table 指令打印表头:
bash
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}\t{{.Status}}"
9. 高级示例
-
输出容器所有环境变量:
bashdocker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' <container> -
自定义 JSON 输出(非标准,但可组合):
bashdocker inspect --format "{ID:'{{.ID}}',Names:'{{.Names}}',Status:'{{.Status}}'}" -
查看可用字段:先用
{``{json .}}输出完整结构bashdocker ps --format '{{json .}}' # 查看 docker ps 的字段 docker inspect --format '{{json .}}' <container> # 查看 inspect 字段
总结
--format 是 Docker CLI 的强大工具,结合 Go 模板,能实现从简单字段提取到复杂格式化的各种需求。建议先用 {``{json .}} 探索数据结构,再逐步构建模板。
更多函数和示例参考 Docker 官方格式化文档:https://docs.docker.com/config/formatting/ 和 Go 模板文档。
通过这些技巧,你可以让 Docker 输出更简洁、更易脚本处理!