- CLI
- 开发工具
【免费下载链接】cli
The Docker CLI
docker ps是 Docker CLI 中用于列出容器的核心命令,也是日常排查容器状态、定位运行实例时使用频率最高的命令之一。本文基于当前仓库中docs/reference/commandline/ps.md的命令参考文档,结合cli/command/container/list.go的实现源码与测试用例,系统讲解docker ps的完整选项、过滤语法、Go 模板格式化能力及其底层调用链,帮助你从"会用"进阶到"用得精准"。
命令概览与别名
docker ps用于列出容器,其完整定义为 "List containers"。在 Docker CLI 的命令结构中,该命令位于 container 子命令组下,拥有四个等价别名:
docker container lsdocker container listdocker container psdocker ps
在源码中,newListCommand直接复用了newPsCommand构建的 Cobra 命令,并为其挂上ps、list两个别名(见 cli/command/container/list.go),因此无论你习惯输入docker ps还是docker container ls,得到的都是同一套参数与行为。
docker ps不接受位置参数(源码中通过Args: cli.NoArgs约束),所有行为均由选项控制,基本语法为:
docker ps [OPTIONS]选项总览
以下为docker ps支持的全部选项(来自 docs/reference/commandline/ps.md):
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
-a,--all | bool | — | 显示所有容器(默认仅显示运行中的容器) |
-f,--filter | filter | — | 按给定条件过滤输出 |
--format | string | — | 使用自定义模板格式化输出:table(默认,带表头的表格)、table TEMPLATE(按给定 Go 模板输出表格)、json(JSON 格式)、TEMPLATE(按给定 Go 模板输出)。模板格式化的详细语法可参考 Docker 官方格式化文档 |
-n,--last | int | -1 | 显示最近创建的 n 个容器(包含所有状态) |
-l,--latest | bool | — | 显示最近创建的 1 个容器(包含所有状态) |
--no-trunc | bool | — | 不截断输出 |
-q,--quiet | bool | — | 仅显示容器 ID |
-s,--size | bool | — | 显示容器总文件大小 |
这些选项在 cli/command/container/list.go 中被逐一注册为 Cobra 标志,其中--filter使用opts.FilterOpt类型,支持重复传入多个过滤条件。
默认输出行为
不带任何选项运行时,docker ps只显示运行中的容器。默认输出的列由源码中的defaultContainerTableFormat常量定义(见 cli/command/formatter/container.go):
table {{.ID}} {{.Image}} {{.Command}} {{.RunningFor}} {{.Status}} {{.Ports}} {{.Names}}即默认表格包含七列:CONTAINER ID、IMAGE、COMMAND、CREATED、STATUS、PORTS、NAMES。若指定--size,表格末尾会追加{{.Size}}列。
几个值得注意的默认行为:
- ID 截断:默认情况下容器 ID 与镜像引用会被截断显示,只有使用
--no-trunc才展示完整 ID。这一逻辑位于 ContainerContext.ID()。 - PORTS 合并:
docker ps会把连续暴露的端口合并为一个区间,例如同时暴露 TCP 端口100、101、102的容器会显示为100-102/tcp。 - NAMES 去斜杠:容器名会去掉 API 返回的前导
/前缀;截断模式下只显示第一个主名称(见 ContainerContext.Names())。
对应的默认输出样式可参考测试基准文件 cli/command/container/testdata/container-list-without-format.golden。
常用选项详解
显示所有容器(-a, --all)
docker ps默认只列出运行中的容器。要看到包括已停止、已退出在内的所有容器,使用-a或--all:
$ docker ps -a不截断输出(--no-trunc)
使用--no-trunc显示完整的容器 ID 与完整命令,适合需要精确引用容器 ID 或查看完整启动命令的场景:
$ docker ps --no-trunc CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ca5534a51dd04bbcebe9b23ba05f389466cf0c190f1f8f182d7eea92a9671d00 ubuntu:24.04 bash 17 seconds ago Up 16 seconds 3300-3310/tcp webapp 9ca9747b233100676a48cc7806131586213fa5dab86dd1972d6a8732e3a84a4d crosbymichael/redis:latest /redis-server --dir 33 minutes ago Up 33 minutes 6379/tcp redis,webapp/db从源码看,--no-trunc通过Trunc: !options.noTrunc传入格式化上下文(见 cli/command/container/list.go),决定 ID、镜像、命令等字段是否被截断。
显示磁盘占用(-s, --size)
--size(或-s)会为每个容器显示两种磁盘占用信息:
$ docker ps --size CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE e90b8831a4b8 nginx "/bin/bash -c 'mkdir " 11 weeks ago Up 4 hours my_nginx 35.58 kB (virtual 109.2 MB) 00c6131c5e30 telegraf:1.5 "/entrypoint.sh" 11 weeks ago Up 11 weeks my_telegraf 0 B (virtual 209.5 MB)- size(可写层大小):容器可写层在磁盘上实际占用的数据量;
- virtual size(虚拟大小):容器使用的只读镜像数据与可写层合计的磁盘占用。
该字段由 ContainerContext.Size() 渲染,格式为35.58 kB (virtual 109.2 MB)。由于计算容器大小是相对昂贵的操作,CLI 默认不会请求该数据——这一点在下面的"格式化与源码实现"章节会进一步展开。
仅显示容器 ID(-q, --quiet)
-q/--quiet只输出容器 ID 列表,非常适合配合xargs等工具做批量操作:
$ docker ps -q a87ecb4f327c 01946d9d34d8在源码中,quiet 模式会切换到DefaultQuietFormat(见 NewContainerFormat())。
最近创建的容器(-n, --last / -l, --latest)
-n, --last <n>:显示最近创建的 n 个容器(包含所有状态),默认值-1表示不限制数量;-l, --latest:显示最近创建的 1 个容器(包含所有状态)。
两者的实现都映射到底层 API 的Limit参数。在 buildContainerListOptions() 中,--last的值直接作为Limit;若指定了--latest且未显式设置--last(last == -1),则Limit被强制为1。对应测试见 cli/command/container/list_test.go。
过滤输出(--filter / -f)
--filter(短选项-f)的格式为key=value键值对;有多个过滤条件时重复传入多个--filter标志,例如--filter "foo=bar" --filter "bif=baz"。过滤器同样会原样传递到底层 API 的Filters字段(见 cli/command/container/list.go),因此过滤能力与 Docker Engine API 保持一致。
docker ps当前支持的过滤器如下:
| 过滤器 | 说明 |
|---|---|
id | 容器 ID |
name | 容器名称 |
label | 任意字符串,表示标签键或键值对,写作<key>或<key>=<value> |
exited | 表示容器退出码的整数,仅在配合--all时有意义 |
status | 取值为created、restarting、running、removing、paused、exited或dead之一 |
ancestor | 过滤共享某个镜像作为祖先的容器,可写<image-name>[:<tag>]、<image id>或<image@digest> |
before/since | 过滤在指定容器(ID 或名称)之前/之后创建的容器 |
volume | 过滤挂载了指定卷或绑定挂载的容器 |
network | 过滤连接到指定网络的容器 |
publish/expose | 过滤发布或暴露指定端口的容器,写作<port>[/<proto>]或<startport-endport>/[<proto>] |
health | 按健康检查状态过滤,取值为starting、healthy、unhealthy或none |
isolation | 仅 Windows 守护进程支持,取值为default、process或hyperv |
is-task | 过滤作为服务"任务"的容器,布尔值(true或false) |
按标签过滤(label)
label过滤器只匹配"存在该标签"的容器,而不关心标签值:
$ docker ps --filter "label=color" CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 673394ef1d4c busybox "top" 47 seconds ago Up 45 seconds nostalgic_shockley d85756f57265 busybox "top" 52 seconds ago Up 51 seconds high_albattani也可同时匹配标签键与标签值:
$ docker ps --filter "label=color=blue" CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d85756f57265 busybox "top" About a minute ago Up About a minute high_albattani按名称过滤(name)
name过滤器匹配名称的全部或部分内容(子串匹配):
$ docker ps --filter "name=nostalgic_stallman" $ docker ps --filter "name=nostalgic" # 子串匹配,可命中多个容器按退出码过滤(exited)
exited过滤器按退出码匹配容器,通常需要配合-a才能看到已退出的容器:
$ docker ps -a --filter 'exited=0'一个常见的排查场景是定位被SIGKILL(信号 9)杀死的容器,其退出码为137:
$ docker ps -a --filter 'exited=137'导致退出码137的常见原因包括:容器内init进程被手动杀死、docker kill杀死容器、Docker 守护进程重启时杀掉了所有运行中的容器。
按状态过滤(status)
status过滤器支持的状态及其含义:
| 状态 | 说明 |
|---|---|
created | 从未启动过的容器 |
running | 由docker start或docker run启动、正在运行的容器 |
paused | 已暂停的容器(参见docker pause) |
restarting | 因容器的重启策略而正在启动的容器 |
exited | 不再运行的容器(进程已完成或被docker stop停止) |
removing | 正在被移除过程中的容器(参见docker rm) |
dead | "僵死"容器,例如因外部进程占用资源而只被部分移除的容器;dead容器无法(重新)启动,只能移除 |
示例:
$ docker ps --filter status=running $ docker ps --filter status=paused按镜像祖先过滤(ancestor)
ancestor过滤器匹配使用指定镜像或其子镜像的容器,支持以下镜像表示形式:
imageimage:tagimage:tag@digestshort-idfull-id
未指定tag时默认使用latest。例如过滤所有使用ubuntu镜像的容器:
$ docker ps --filter ancestor=ubuntu也可以按镜像 ID 对应的层(如d0e008c6cf02)过滤出所有在其层栈中包含该层的容器:
$ docker ps --filter ancestor=d0e008c6cf02按创建时间过滤(before / since)
before只显示在指定容器(ID 或名称)之前创建的容器:
$ docker ps -f before=9c3527ed70cesince只显示在指定容器之后创建的容器:
$ docker ps -f since=6e63f6ff38b0按卷过滤(volume)
volume过滤器匹配挂载了指定卷名或指定挂载路径的容器,可与--format组合查看挂载详情:
$ docker ps --filter volume=remote-volume --format "table {{.ID}}\t{{.Mounts}}" $ docker ps --filter volume=/data --format "table {{.ID}}\t{{.Mounts}}"按网络过滤(network)
network过滤器同时支持网络名称和网络ID:
$ docker run -d --net=net1 --name=test1 ubuntu top $ docker run -d --net=net2 --name=test2 ubuntu top $ docker ps --filter network=net1使用网络 ID 过滤时,可先通过docker network inspect --format "{{.ID}}" net1取得完整 ID 再传入。
按端口过滤(publish / expose)
publish与expose过滤器匹配发布或暴露了指定端口、端口区间及协议的容器;未指定协议时默认为tcp:
$ docker ps --filter publish=80 # 发布端口 80 的容器 $ docker ps --filter expose=8000-8080/tcp # 暴露 8000-8080 TCP 端口的容器 $ docker ps --filter publish=80/udp # 发布 UDP 端口 80 的容器自定义输出格式(--format)
--format使用 Go 模板语法对输出做精细控制,支持四种形式:
table:带列头的表格(默认)table TEMPLATE:使用给定 Go 模板并以表格(带列头)形式输出json:以 JSON 格式输出,每行一个容器对象TEMPLATE:仅按给定 Go 模板输出,不带列头
模板占位符
模板中可用的占位符如下:
| 占位符 | 说明 |
|---|---|
.ID | 容器 ID |
.Image | 镜像 ID |
.Command | 带引号的启动命令 |
.CreatedAt | 容器创建时间 |
.RunningFor | 容器启动至今的时长 |
.Ports | 暴露的端口 |
.State | 容器状态(如created、running、exited) |
.Status | 带时长与健康信息的容器状态 |
.HealthStatus | 容器健康状态(starting、healthy、unhealthy;不可用时为空) |
.Size | 容器磁盘大小 |
.Names | 容器名称 |
.Labels | 分配给容器的全部标签 |
.Label | 指定标签的值,例如{{.Label "com.docker.swarm.cpu"}} |
.Mounts | 容器中挂载的卷名称 |
.Networks | 容器连接的网络名称 |
这些占位符与 ContainerContext 中定义的字段及表头一一对应。
典型用法示例
不带表头,输出由冒号分隔的 ID 与命令:
$ docker ps --format "{{.ID}}: {{.Command}}" a87ecb4f327c: /bin/sh -c #(nop) MA 01946d9d34d8: /bin/sh -c #(nop) MA c1d3b0166030: /bin/sh -c yum -y up 41d50ecd2f57: /bin/sh -c #(nop) MA以表格形式列出所有运行容器的 ID 与标签:
$ docker ps --format "table {{.ID}}\t{{.Labels}}" CONTAINER ID LABELS a87ecb4f327c com.docker.swarm.node=ubuntu,com.docker.swarm.storage=ssd 01946d9d34d8 c1d3b0166030 com.docker.swarm.node=debian,com.docker.swarm.cpu=6 41d50ecd2f57 com.docker.swarm.node=fedora,com.docker.swarm.cpu=3,com.docker.swarm.storage=ssd以 JSON 格式输出,便于程序化解析:
$ docker ps --format json {"Command":"\"/docker-entrypoint.…\"","CreatedAt":"2021-03-10 00:15:05 +0100 CET","ID":"a762a2b37a1d","Image":"nginx","Labels":"maintainer=NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e","LocalVolumes":"0","Mounts":"","Names":"boring_keldysh","Networks":"bridge","Ports":"80/tcp","RunningFor":"4 seconds ago","Size":"0B","State":"running","Status":"Up 3 seconds"}源码实现:docker ps 的底层调用链
理解docker ps的实现有助于预判其行为。核心流程位于 cli/command/container/list.go 的runPs函数,大致分四步:
- 确定格式来源:若命令行未传
--format,则回退读取 CLI 配置文件~/.docker/config.json中的psFormat字段(PsFormat的定义见 cli/config/configfile/file.go)。若同时传了--format和--quiet,则会向 stderr 输出警告WARNING: Ignoring custom format, because both --format and --quiet are set.。 - 构造 API 请求参数:
buildContainerListOptions将 CLI 选项映射为client.ContainerListOptions(All、Limit、Size、Filters)。 - 调用引擎 API:通过
dockerCLI.Client().ContainerList(ctx, listOptions)获取容器列表。 - 格式化渲染:构造
formatter.Context后由formatter.ContainerWrite统一渲染(见 cli/command/formatter/container.go)。
模板预校验与 Size 自动探测
buildContainerListOptions中有一段值得注意的优化逻辑(见 cli/command/container/list.go):当指定了--format时,CLI 会先解析并执行模板,做两件事:
- 预校验模板合法性:模板解析或执行失败会立即报错,避免把错误模板发给守护进程后才发现问题;
- 自动启用
--size:因为请求容器大小是昂贵的操作,CLI 默认不请求该数据。但如果模板中使用了.Size字段,ContainerContext会通过FieldsUsed机制记录下来,CLI 据此自动把Size置为true(见 cli/command/formatter/container.go)。当然,显式传入--size=false可以强制关闭这一自动行为。
这一行为在 cli/command/container/list_test.go 的TestContainerListFormatSizeSetsOption中有完整覆盖:模板含.Size时自动开启,仅含.Names时保持关闭,--size=false可覆盖自动探测。
错误处理与边界情况
测试用例(cli/command/container/list_test.go)验证了以下错误场景:
- 模板中引用了未定义的函数(如
{{invalid}})会报错function "invalid" not defined; - 模板函数参数个数错误(如
{{join}})会报错wrong number of args for join; - 底层 API 调用失败时错误会原样透出。
此外,docker ps的格式化输出对容器名含/的情况做了特殊处理:截断模式下只选取第一个非 legacy link 的名称(如foo/bar只显示foo),该场景同样有对应测试(cli/command/container/list_test.go)。
通过配置文件自定义默认格式
如果你希望docker ps每次都以自定义模板输出,而无需反复输入--format,可以在~/.docker/config.json中设置psFormat:
{ "psFormat": "table {{.Names}}\t{{.Image}}\t{{.Labels}}\t{{.Size}}" }配置生效后,未显式指定--format的docker ps调用都会使用该模板。对应测试见 cli/command/container/list_test.go。
常见组合实战
最后汇总几个高频实战组合:
# 查看所有容器(含已停止),仅输出 ID,便于批量操作 docker ps -aq # 按标签定位业务容器 docker ps --filter "label=project=web" # 找出最近启动失败的容器 docker ps -a --filter "exited=1" --filter "status=exited" # 列出容器并同时展示挂载卷与磁盘大小 docker ps -as --format "table {{.ID}}\t{{.Names}}\t{{.Mounts}}\t{{.Size}}" # 以 JSON 输出容器列表供脚本消费 docker ps --format json # 只查看最近创建的 5 个容器(包含所有状态) docker ps -n 5掌握docker ps的选项、过滤器与模板语法,可以让你在容器数量众多的环境中快速定位目标容器,并将输出无缝接入自动化脚本。需要查阅更多细节时,可回到命令参考文档 docs/reference/commandline/ps.md 或同源扩展文档 docs/reference/commandline/container_ls.md。
- CLI
- 开发工具
【免费下载链接】cli
The Docker CLI
相关推荐
BaiduPCS-Go 完整指南:4个场景玩转百度网盘命令行管理
BaiduPCS Go 完整指南:4个场景玩转百度网盘命令行管理 BaiduPCS Go 是一款用 Go 语言编写的百度网盘命令行客户端,加强版在原版基础上加入
CLI开发工具Salt Player 本地音乐播放器完整指南:10 分钟从下载到离线播放(Android + Windows 双端)
Salt Player 本地音乐播放器完整指南:10 分钟从下载到离线播放(Android + Windows 双端) Salt Player(椒盐音乐)是一款
CLI开发工具Docker CLI volume ls:列表、过滤与模板格式化卷输出的完整指南
Docker CLI volume ls:列表、过滤与模板格式化卷输出的完整指南 本文基于 Docker CLI(cli 仓库)中 docker volume
CLI开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考