在Docker中查看运行/停止容器的完整命令

398

我如何在Docker中查看正在运行的容器/进程的完整命令?

$ docker ps --all
CONTAINER ID    IMAGE          COMMAND                 CREATED          STATUS                     PORTS    NAMES
5b6291859b61    nginx:1.7.8    "nginx -g 'daemon of    4 minutes ago    Exited (0) 4 minutes ago            thirsty_brattain

我只能看到这里的 "nginx -g 'daemon of".. ",而不是完整的命令。


2
请参见此处:https://dev59.com/_FwY5IYBdhLWcg3wU2XA - Tilo
6个回答

796

docker ps --no-trunc命令将显示正在运行的容器的完整命令和其他详细信息。


5
这对我没用。它给了我命令,但并没有提供所有的开关(当我使用“完整命令”时,这就是我想到的)。上面提到的runlike命令对我效果更好。 - Dylan Smith
1
只运行容器的完整命令是删除所有命令。docker ps --no-trunc - Jacob Morris
谢谢 - 已更正。我的先前命令是针对所有容器而不是只有正在运行的容器,这是最初的问题。 - Scott S.
未截断的命令可能非常长,使用 docker ps --all --no-trunc | cut -c-400 命令每行仅显示前 400 个字符。 - rubo77
3
为了更方便地阅读,该命令可以通过管道符号 | 传输到 less 命令中,具体操作为 docker ps --no-trunc | less -S。这会消除换行并允许您横向滚动。 - Aleksandr Erokhin

196

使用:

docker inspect -f "{{.Name}} {{.Config.Cmd}}" $(docker ps -a -q)

...它为所有容器执行“docker inspect”操作。


11
这并未显示 "docker ps" 命令。"docker ps" 命令对应于 "docker inspect Path and Args"。 - JDiMatteo
3
2018年1月以来不太好。 - s g
6
docker inspect -f "{{.Name}} {{.Path}} {{.Args}}" $(docker ps -a -q)意思是查询所有已经停止的Docker容器的名称、进程路径和参数。 - Paul
2
如果你只是在命令前面加上 sudo,由于第二次调用获取所有容器名称,你会得到 "docker inspect" requires at least 1 argument(s). 的错误提示,你可能需要在 $( 内部添加一个 sudo。 - RandomInsano
对于那些想更好地理解“-f”查询的人,我在这里找到了一个很好的解释:https://container-solutions.com/docker-inspect-template-magic/。 - intijk

23

使用:

docker inspect -f "{{.Path}} {{.Args}} ({{.Id}})" $(docker ps -a -q)

这将显示命令路径和参数,类似于docker ps


你如何修改它以搜索特定命令,例如 kube-apiserver - Jonathan
@Jonathan docker inspect -f "{{.Path}} {{.Args}} ({{.Id}})" $(docker ps -a -q) | grep kube-apiserver@Jonathan,执行以上命令可以获取正在运行的容器中包含“kube-apiserver”的部分信息。 - rrw

23

TL-DR

docker ps --no-truncdocker inspect CONTAINER提供了启动容器的入口点及其命令,但可能会丢失某些部分,例如${ANY_VAR},因为容器环境变量不会作为解析结果打印出来。

为了克服这个问题,docker inspect CONTAINER有一个优势,它还允许从Config.Env属性中分别检索在容器中定义的环境变量及其值。

docker psdocker inspect提供有关执行入口点及其命令的信息。通常,这是一个包装入口点脚本(.sh)而不是容器启动的“真正”程序。要获取有关此信息的信息,请使用ps/proc/1/cmdline请求进程信息。


1)docker ps --no-trunc

它打印所有正在运行的容器的入口点和所执行的命令。虽然它打印传递给入口点的命令(如果我们传递了它),但不显示Docker环境变量的值(例如$FOO${FOO})。

例如,运行alpine容器:

docker run --name alpine-example -e MY_VAR=/var alpine:latest sh -c 'ls $MY_VAR'

当使用像下面这样的docker -ps命令:

docker ps -a --filter name=alpine-example --no-trunc

它的输出为:

CONTAINER ID           IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
5b064a6de6d8417...   alpine:latest       "sh -c 'ls $MY_VAR'"   2 minutes ago       Exited (0) 2 minutes ago                       alpine-example

我们可以看到传递给entrypoint的命令:sh -c 'ls $MY_VAR',但是实际上$MY_VAR没有被解析。

2)docker inspect CONTAINER

当我们检查alpine-example容器时:

docker inspect alpine-example | grep -4 Cmd

虽然有命令,但我们仍然看不到环境变量的值:

        "Cmd": [
            "sh",
            "-c",
            "ls $MY_VAR"
        ],

事实上,我们无法通过这些docker命令看到插值变量。
然而,作为一种权衡,我们可以使用docker inspect分别显示容器的命令和环境变量:
docker inspect  alpine-example  | grep -4 -E "Cmd|Env"

这将会打印:

        "Env": [
            "MY_VAR=/var",
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
        ],
        "Cmd": [
            "sh",
            "-c",
            "ls $MY_VAR"
        ]

更符合docker的方式是使用docker inspect命令的--format标志,它允许指定要呈现的JSON属性:
docker inspect --format '{{.Name}} {{.Config.Cmd}}  {{ (.Config.Env) }}'  alpine-example

这将输出:

/alpine-example [sh -c ls $MY_VAR]  [MY_VAR=/var PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]

3) 对于正在运行的容器,从容器本身中检索启动的进程

Docker执行的入口点和命令可能有所帮助,但在某些情况下,这是不够的,因为这只是一个负责启动真正/核心进程的包装入口点脚本(.sh)。
例如,当我运行Nexus容器时,执行并显示运行容器的命令是"sh -c ${SONATYPE_DIR}/start-nexus-repository-manager.sh"
对于PostgreSQL,它是"docker-entrypoint.sh postgres"

要获取更多信息,我们可以在运行的容器上执行docker exec CONTAINER ps aux
它可能会打印其他我们可能不感兴趣的进程。
为了缩小到入口点启动的初始进程,我们可以执行以下操作:

docker exec CONTAINER ps -1

我指定1是因为entrypoint所执行的进程通常具有1 ID。

即使没有ps,我们仍然可以在/proc/1/cmdline中找到信息(在大多数Linux发行版中,但不是所有发行版都是如此)。例如:

docker exec CONTAINER cat /proc/1/cmdline | sed -e "s/\x00/ /g"; echo    

如果我们可以访问启动容器的Docker主机,另一个获取entrypoint执行的进程完整命令的替代方法是:

执行 ps -PID,其中PID是Docker守护程序创建的用于运行容器的本地进程,例如:

ps -$(docker container inspect --format '{{.State.Pid}}'  CONTAINER)

使用docker ps实现易于理解的格式化

docker ps --no-trunc并不总是易于阅读。指定要打印的列并以表格形式呈现可能会使其更好:

docker ps   --no-trunc  --format "table{{.Names}}\t{{.CreatedAt}}\t{{.Command}}"

创建别名可能会有所帮助:
alias dps='docker ps   --no-trunc  --format "table{{.Names}}\t{{.CreatedAt}}\t{{.Command}}"'

简而言之,但是因为展示了输出示例,所以点赞。 - Skippy le Grand Gourou

19
将 Dylan 的评论转化为一篇完整的答案,因为它非常有用:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike YOUR-CONTAINER

它是做什么的?在容器内运行 https://github.com/lavie/runlike,为您获取完整的docker run命令,然后自动删除容器。


17

使用 runlike git仓库的代码 https://github.com/lavie/runlike

安装 runlike

pip install runlike

由于它接受容器 ID 作为参数,因此要提取容器 ID,请使用以下命令

docker ps -a -q

你可以使用 runlike 命令提取完整的 Docker 运行命令,命令如下:

runlike <docker container ID>

无法工作。显示“命令 '['docker','inspect',u'06e6a369f909']'返回非零退出状态1” - fstang
你是否按照我提到的安装了 runlike? - Abhishek Jain
11
更好的方法是在 Docker 容器内运行 Runlike,避免安装它:docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike YOUR-CONTAINER - Dylan Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接