-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”)