美文网首页k8s
20230312--从Docker命令format参数到Go模板

20230312--从Docker命令format参数到Go模板

作者: 負笈在线 | 来源:发表于2023-03-11 20:12 被阅读0次

从Docker命令format参数到Go模板语法

在使用Docker的过程中,有时候需要格式化输出的内容,以便进一步的自动化处理,通常情况下利用awk、sed、grep等shell命令来实现;但事实上Docker CLI的--format参数提供了基于Go模版的日志格式化输出的辅助功能,并提供了一些内置的增强函数。

1.一个简单的例子:列出所有容器的IP地址

1)docker inspect [CONTAINER ID]中包含容器的名称及运行状态
# docker inspect 0448073ebae8
[
    {
        ...
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 975915,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-03-10T03:24:02.259753658Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        ...
        "Name": "/local_cmdb_nginx_1",
        ...
2)获取单个容器的名称及状态
# docker inspect --format='{{.Name}} {{.State.Running}}' 0448073ebae8
/local_cmdb_nginx_1 true
**说明**
{{.Name}}获取json一级结构下数据
{{.State.Running}}或者json二级结构下获取
3)完整命令
# docker inspect --format='{{.Name}} {{.State.Running}}' $(docker ps -aq)
/local_cmdb_nginx_1 true
/local_cmdb_django_1 true

2.Go模版语法

1)注释

格式:

{{/*注释内容*/}}

例子:

# docker inspect --format='{{/*查看所有容器的运行状态*/}}{{.Name}} {{.State.Running}}' $(docker ps -aq)
2)系统变量

格式:

{{.}}

例子:

获取所有容器的名称
# docker inspect --format='{{.Name}}' $(docker ps -aq)

点号表示当前对象及上下文,可以直接通过{{.}}获取当前对象。如果返回结果也是一个 Struct 对象(Json 中以花括号/大括号包含),则可以直接通过点号级联调用,获取子对象的指定属性值。

注意: 如果需要获取的属性名称包含点号(比如下列示例数据)或者以数字开头,则不能直接通过级联调用获取信息。因为属性名称中的点号会被解析成级联信息,进而导致返回错误结果。即便使用引号将其包含也会提示语法格式错误。此时,需要通过 index 来读取指定属性信息。

        "Labels": {
            "com.docker.compose.config-hash": "b641ebeed1cbd39801decb883317589830c6072c0c897a2fabb53ca31811081b",
            "com.docker.compose.container-number": "1",
            "com.docker.compose.oneoff": "False",
            "com.docker.compose.project": "local_cmdb",
            "com.docker.compose.project.config_files": "docker-compose.yml",
            "com.docker.compose.project.working_dir": "/root/local_cmdb",
            "com.docker.compose.service": "nginx",
            "com.docker.compose.version": "1.26.0",
            "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
        },
无法获取
# docker inspect --format='{{.Config.Labels.com.docker.compose.project.working_dir}}' 0448073ebae8
<no value>
index获取
# docker inspect --format='{{index .Config.Labels "com.docker.compose.project.working_dir"}}' 0448073ebae8
/root/local_cmdb
3)遍历(循环):range

格式:

{{range pipeline}}{{.}}{{end}}
{{range pipeline}}{{.}}{{else}}{{.}}{{end}}

range 用于遍历结构内返回值的所有数据。支持的类型包括 array, slice, mapchannel。使用要点:

  • 对应的值长度为 0 时,range 不会执行。
  • 结构内部如要使用外部的变量,需要在前面加 引用,比如Var2。
  • range 也支持 else 操作。效果是:当返回值为空或长度为 0 时执行 else 内的内容。

例子:

# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
172.20.0.2
172.19.0.2
172.18.0.2
172.18.0.6
4)index

如果返回结果是一个 map, slice, array 或 string,则可以使用 index 加索引序号(从零开始计数)来读取属性值。

# docker inspect bridge --format '{{.IPAM.Config}}'
[{172.17.0.0/16  172.17.0.1 map[]}]
# docker inspect bridge --format '{{(index .IPAM.Config 0).Gateway}}'
172.17.0.1
5)自定义变量

可以在处理过程中设置自定义变量,然后结合自定义变量做更复杂的处理。 如果自定义变量的返回值是对象,则可以通过点号进一步级联访问其属性。比如 {{$Myvar.Field1}}

# docker inspect --format '{{.NetworkSettings.Ports}}' 0448073ebae8
map[80/tcp:[{0.0.0.0 80} {:: 80}]]
# docker inspect --format '{{range $p1,$p2 := .NetworkSettings.Ports}}{{$p1}}{{end}}' 0448073ebae8
80/tcp
# docker inspect --format '{{range $p1,$p2 := .NetworkSettings.Ports}}{{$p2}}{{end}}' 0448073ebae8
[{0.0.0.0 80} {:: 80}]
6)基本判断if...not...end

返回单一参数的布尔否定值,即返回输入参数的否定值。

例子:

# 如果容器的 restarting 设置为 false,则返回信息“容器没有配置重启策略”
docker inspect --format '{{.Name}}>>{{if not .State.Restarting}}容器没有配置重启策略{{end}}' $(docker ps -q)
7)基本判断or
  • {{or x y}}: 表示如果 x 为真返回 x,否则返回 y。
  • {{or x y z}}:后面跟多个参数时会逐一判断每个参数,并返回第一个非空的参数。如果都为 false,则返回最后一个参数。
  • 除了 null(空)和 false 被识别为 false,其它值(字符串、数字、对象等)均被识别为 true。

例子:

# docker inspect --format '{{.Name}}>>{{or .State.Status .State.Restarting}}' $(docker ps -q)
8)条件判断:if 判断条件

基本格式:{{if 判断条件 .Var1 .Var2}}{{end}}

  • eq: 相等,即 arg1 == arg2。比较特殊的是,它支持多个参数进行与比较,此时,它会将第一个参数和其余参数依次比较,返回下式的结果:
{{if eq true .Var1 .Var2 .Var3}}{{end}}
# 效果等同于:
arg1==arg2 || arg1==arg3 || arg1==arg4 ...
  • ne: 不等,即 arg1 != arg2。
  • lt: 小于,即 arg1 < arg2。
  • le: 小于等于,即 arg1 <= arg2。
  • gt: 大于,即 arg1 > arg2。
  • ge: 大于等于,即 arg1 >= arg2。
9)条件判断:if else

格式:

{{if pipeline}}{{end}}
{{if pipeline}}{{else}}{{if pipeline}}{{end}}{{end}}
{{if pipeline}}{{else if pipeline}}{{else}}{{end}}

例子:

# 输出所有已停止的容器名称:
# docker inspect --format '{{if ne 0 .State.ExitCode}}{{.Name}}{{end}}' $(docker ps -aq)
# docker inspect --format '{{.Name}}>>''{{if ne 0 .State.ExitCode}}{{.Name}}{{else}}该容器还在运行{{end}}' $(docker ps -aq)
# docker inspect --format '{{.Name}}>>''{{if ne 0 .State.ExitCode}}{{.Name}}{{else if .}}该容器还在运行{{end}}' $(docker ps -aq)

# 输出所有已停止或配置了 Restarting 策略的容器名称
docker inspect --format '{{if ne 0.0 .State.ExitCode}}{{.Name}}{{else if eq .State.Restarting true}}容器{{.Name}}配置了Restarting策略.{{else}}{{end}}' $(docker ps -aq)
10)打印信息

docker --format 默认调用 go语言的 print 函数对模板中的字符串进行输出。而 go语言还有另外 2 种相似的内置函数,对比说明如下:

  • print: 将传入的对象转换为字符串并写入到标准输出中。如果后跟多个参数,输出结果之间会自动填充空格进行分隔。
  • println: 功能和 print 类似,但会在结尾添加一个换行符。也可以直接使用 {{println}} 来换行。
  • printf: 与 shell 等环境一致,可配合占位符用于格式化输出。

例子:

# docker inspect --format '{{.Name}}>>''{{.State.Pid}}{{.State.ExitCode}}' $(docker ps -aq)
/local_cmdb_nginx_1>>9759150
# docker inspect --format '{{.Name}}>>''{{print .State.Pid .State.ExitCode}}' $(docker ps -aq)
/local_cmdb_nginx_1>>975915 0
# docker inspect --format '{{.Name}}>>''{{.State.Pid}}{{println " 从这换行"}}{{.State.ExitCode}}'  $(docker ps -aq)
/local_cmdb_nginx_1>>975915 从这换行
0
# docker inspect --format '{{.Name}}>>''{{printf "Pid:%d ExitCode:%d" .State.Pid .State.ExitCode}}'  $(docker ps -aq)
/local_cmdb_nginx_1>>Pid:975915 ExitCode:0
11)管道

管道 即 pipeline ,与 shell 中类似,可以是上下文的变量输出,也可以是函数通过管道传递的返回值。

例子:

# docker inspect --format '{{.Name|printf "Pid:%d" .State.Pid}}'  $(docker ps -aq)
12)内置函数len

内置函数 len 返回相应对象的长度。

例子:

# docker inspect --format '{{len .Name}}'  $(docker ps -aq)

3.Docker增强模版及函数

Docker 基于 go模板的基础上,构建了一些内置函数。

1)json

Docker 默认以字符串显示返回结果。而该函数可以将结果格式化为压缩后的 json 格式数据。

# 获取 Config 字段对应的 json 数据
# docker inspect --format='{{json .Config}}' $(docker ps -aq)
{"Test":["CMD-SHELL","netstat -ltun|grep 10514"]},"Image":"goharbor/harbor-log:v2.3.2","Volumes":{"/etc/logrotate.d/":{},"/run/":{},"/var/log/docker":{},"/var/log/docker/":{}},"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{"base-build-date":"20210818","build-date":"20210813","com.docker.compose.config-hash":"9f8afc063a1231ca6ffa5bc46bc70306abb22ae5c1d92e17b1f04fff6215883b","com.docker.compose.container-number":"1","com.docker.compose.oneoff":"False","com.docker.compose.project":"harbor","com.docker.compose.project.config_files":"docker-compose.yml","com.docker.compose.project.working_dir":"/root/harbor","com.docker.compose.service":"log","com.docker.compose.version":"1.26.0","name":"Photon OS x86_64/4.0 Base Image","vendor":"VMware"}}
2)join

用指定的字符串将返回结果连接后一起展示。操作对象必须是字符串数组。

# 输出容器配置的所有 Entrypoint 参数,以 " , " 分隔:
# docker inspect --format '{{join .Config.Entrypoint " , "}}' $(docker ps -aq)
/bin/sh , -c , /usr/local/bin/uwsgi -i /root/local_cmdb/local_cmdb/local_cmdb.ini
3)lower

将返回结果中的字母全部转换为小写。操作对象必须是字符串。

# docker inspect --format "{{lower .Name}}" $(docker ps -aq)
/local_cmdb_nginx_1
4)upper

将返回结果中的字母全部转换为大写。操作对象必须是字符串。

# docker inspect --format "{{upper .Name}}" $(docker ps -aq)
/LOCAL_CMDB_NGINX_1
5)title

将返回结果的首字母转换为大写。操作对象必须是字符串,而且不能是纯数字。

# docker inspect --format "{{title .State.Status}}" $(docker ps -aq)
Running
6)split

使用指定分隔符将返回结果拆分为字符串列表。操作对象必须是字符串且不能是纯数字。同时,字符串中必须包含相应的分隔符,否则会直接忽略操作。

# docker inspect --format '{{split .HostsPath "/"}}' $(docker ps -aq)
[ var lib docker containers 0448073ebae814ecf79e267f6d8742bcfc18df269726ca57858d75323f175c08 hosts]

参考URL

https://developer.aliyun.com/article/230067
https://www.jianshu.com/p/1b4cfed37feb

相关文章

  • Docker常用命令

    Docker命令源代码 Docker的源代码全部是用Go语言写的。其中, commands.go 是docker的...

  • docker-compse 启动nginx

    模板如下: 启动命令:docker-compose -f docker-compose-nignx.yaml up -d

  • docker-compose启动mongodb

    模板如下: 启动命令:docker-compose -f docker-compose-mongo.yaml up -d

  • centos7基于容器方式启动fabric网络

    下载Compose模板文件 go get github.com/yeasy/docker-compose-file...

  • 删除ACM Latex模板版权信息

    三条命令去除ACM sigconf latex模板里的ACM reference format和copyright信息。

  • Golang标准库——go(3)

    format importer parser printer scanner format format包实现Go...

  • docker

    三大要素 仓库 镜像 容器镜像即模板容器即为一个模板的实例 docker常用命令 docker version d...

  • Docker 基本命令

    docker的基本命令 docker version :查看docker的版本号,包括客户端、服务端、依赖的Go等...

  • nsenter

    使用场景:当需要在容器中调试网络,而容器没有安装调试命令,可以通过docker inspect --format ...

  • Docker之compose

    Compose模板配置 YAML格式 docker-compose.yml 命令列表 运行 compose 项目 ...

网友评论

    本文标题:20230312--从Docker命令format参数到Go模板

    本文链接:https://www.haomeiwen.com/subject/fanxrdtx.html