说实话,我一直感到困惑docker exec -it …,docker exec -i …并且docker exec -t …,所以我决定做一个测试:
docker exec -it …
docker exec -i …
docker exec -t …
# 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 115c89122e72 bash
^C
该命令挂起,我必须使用Ctl+ c来中断它。
Ctl
c
# docker exec -t 115c89122e72 bash
root@115c89122e72:/# ls ^C
它成功进入容器,但挂起执行第一个命令。
因此,似乎没有必要使用docker exec -i …and docker exec -t …命令。谁能详细说明为什么存在该命令-i及其-t选项docker exec?
-i
-t
docker exec
-i,--interactive即使没有连接,也可以保持STDIN处于打开状态,如果您完全想键入任何命令,都需要打开。
--interactive
-t,--tty分配一个伪TTY,一个伪终端,它将用户的“终端”与stdin和stdout连接起来。(请参阅container/container.go)
--tty
container/container.go
如果执行回显,则仅-t需要。 但是对于在其中输入输入的交互式会话,则需要-i。
由于-i保持stdin处于打开状态,因此还可以使用它来将输入通过管道传递到分离的docker容器。即使使用-d(分离)也可以。
-d
$ echo hello | docker run -i busybox cat hello
-i 即使未连接STDIN也保持打开状态,在这种情况下STDOUT的状态是什么?
它是docker exec由设置的docker run。
docker run
但是,关于docker exec,存在一个当前问题(问题8755:Docker tty不是具有docker exec
不幸的是,您的发现仅相当于tty在centos6与ubuntu:14.04之间的行为差异。exec内仍然没有功能性tty-只需执行一下ls -la /proc/self/fd/0,看看它是指向a pts不存在的断开链接。 我们正在处理的实际错误是某些标准库假定/ proc / self / fds /中的符号链接必须是有效的符号链接。 问题在于,tty是在主机外部创建的,在容器中没有对它的引用,就像/dev/console在主容器中如何设置一样。 解决此问题的一种方法是分配并将绑定devpts从主机装入到容器中。
不幸的是,您的发现仅相当于tty在centos6与ubuntu:14.04之间的行为差异。exec内仍然没有功能性tty-只需执行一下ls -la /proc/self/fd/0,看看它是指向a pts不存在的断开链接。
ls -la /proc/self/fd/0
pts
我们正在处理的实际错误是某些标准库假定/ proc / self / fds /中的符号链接必须是有效的符号链接。
问题在于,tty是在主机外部创建的,在容器中没有对它的引用,就像/dev/console在主容器中如何设置一样。 解决此问题的一种方法是分配并将绑定devpts从主机装入到容器中。
/dev/console
devpts
注意(2017年第四季度):该问题现在应该已修复(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”)
tty
not a tty