“docker exec”命令的“-i”和“-t”选项的目的是啥?

Posted

技术标签:

【中文标题】“docker exec”命令的“-i”和“-t”选项的目的是啥?【英文标题】:What is the purpose of the "-i" and "-t" options for the "docker exec" command?“docker exec”命令的“-i”和“-t”选项的目的是什么? 【发布时间】:2016-06-03 16:55:47 【问题描述】:

说实话,我一直对docker exec -it …docker exec -i …docker exec -t …感到困惑,所以我决定做一个测试:

    docker exec -it …:

    # docker exec -it 115c89122e72 bash
    root@115c89122e72:/# ls
    bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    

    正常工作。

    docker exec -i …:

    # docker exec -i 115c89122e72 bash
    ^C
    

    命令挂起,我必须使用 Ctl + c 来中断它。

    docker exec -t …:

    # docker exec -t 115c89122e72 bash
    root@115c89122e72:/# ls
    ^C
    

    成功进入容器,但在执行第一个命令时挂起。

因此,使用docker exec -i …docker exec -t … 命令似乎没有意义。谁能详细说明为什么docker exec 命令存在-i-t 选项?

【问题讨论】:

【参考方案1】:

-i, --interactive 即使没有附加 STDIN 也会保持打开状态,如果你想输入任何命令,你需要它。

-t, --tty 分配一个伪 TTY,一个 pseudo terminal,它将用户的“终端”与标准输入和标准输出连接起来。 (见container/container.go

如果您执行回显,则只需要 -t。 但是对于输入输入的交互式会话,您需要-i

由于-i 保持标准输入打开,它还用于将输入通过管道传输到分离的 docker 容器。即使使用-d(分离)也可以。 见“When would I use --interactive without --tty in a Docker container?”:

$ echo hello | docker run -i busybox cat
  hello

-i即使没有连接也保持STDIN打开,这种情况下STDOUT的状态是什么?

对于docker exec,是docker run设置的那个。

但是,关于docker exec,目前存在一个问题(issue 8755: Docker tty is not a tty with docker exec

不幸的是,您的发现仅相当于 tty 在 centos6 与 ubuntu:14.04 中的行为之间的差异。 exec 中仍然没有功能性 tty - 只需执行 ls -la /proc/self/fd/0 并查看它是指向不存在的 pts 的断开链接。

我们正在处理的实际错误是某些标准库假定 /proc/self/fds/ 中的符号链接必须是有效的符号链接

问题是 tty 是在主机外部创建的,并且在容器中没有对它的引用,就像在主容器中设置 /dev/console 一样。 解决此问题的一种方法是将主机上的devpts 分配并绑定挂载到容器中。

注意(2017 年第四季度):this should been fixed by now (docker 17.06-ce). 见PR 33007。

该 PR 现在允许(自 17.06 起):

zacharys-pro:dev razic$ docker run --rm -t -d ubuntu bash
83c292c8e2d13d1b1a8b34680f3fb95c2b2b3fef71d4ce2b6e12c954ae50965a

zacharys-pro:dev razic$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
83c292c8e2d1        ubuntu              "bash"              2 seconds ago       Up 1 second                             xenodochial_bardeen

zacharys-pro:dev razic$ docker exec -ti xenodochial_bardeen tty
/dev/pts/1

(在 17.06 之前,tty 正在返回“not a tty”)

【讨论】:

-i 保持STDIN打开即使没有附加,这种情况下STDOUT的状态是什么? @NanXiao 这取决于图像。请参阅编辑后的答案。 很抱歉再次打扰您。实际上,我想问的问题是 STDOUT 始终是开放的,对吗?谢谢! @NanXiao 如果 docker run 分配了标准输出,则打开它(在这种情况下,docker exec 不需要 -i,它将使用 docker run 设置的一个,除了在 CentOS6 上,它将不工作,因此我提到的错误) @NanXiao 另请参阅andykdocs.de/development/Docker/… 以了解 docker run 设置 tty 的必要性。

以上是关于“docker exec”命令的“-i”和“-t”选项的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

docker run 和 docker exec 的差异

19-Docker-常用命令详解-docker exec

docker run VS docker exec 的区别

使用docker exec命令

使用 docker exec 执行两个命令

docker exec 和 docker attach 的区别