"-i"的目的是什么?和"-t" "docker exec"的选项命令? [英] What is the purpose of the "-i" and "-t" options for the "docker exec" command?
问题描述
说实话,我一直对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
选项?
-i
,--interactive
即使未连接STDIN也会保持打开状态,如果您根本想键入任何命令,都需要打开它.
-t
,--tty
分配一个伪TTY,即伪终端,其中用stdin和stdout连接用户的终端". (请参见 container/container.go
)>
如果执行回显,则仅需要-t
.
但是对于在其中输入输入的交互式会话,您需要-i
.
由于-i
使stdin保持打开状态,因此也可以使用它来将输入通过管道传递到分离的docker容器.即使使用-d
(分离)也可以.
请参阅"何时在Docker容器中使用不带--tty
的--interactive
?":
$ echo hello | docker run -i busybox cat
hello
-i
即使未连接STDIN也会保持打开状态,在这种情况下STDOUT的状态是什么?
对于docker exec
,它是docker run
设置的一个.
但是,关于 docker exec
,当前存在问题(问题8755:Docker tty不是具有docker exec
不幸的是,您的发现仅相当于tty在centos6与ubuntu:14.04之间的行为差异. exec内仍然没有功能性tty-只需执行
ls -la /proc/self/fd/0
并查看它是指向不存在的pts
的断开链接即可.我们要处理的实际错误是某些标准库假定/proc/self/fds/中的符号链接必须是有效的符号链接
问题在于,tty是在主机外部创建的,并且在容器中没有对它的引用,就像在主容器中设置
/dev/console
的方式一样.
解决此问题的一种方法是分配devpts
并将其从主机绑定安装到容器中.
注意(2017年第4季度):目前应已解决(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
")
To be honest, I have always been confused about docker exec -it …
, docker exec -i …
and docker exec -t …
, so I decide to do a test:
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
It works normally.
docker exec -i …
:# docker exec -i 115c89122e72 bash ^C
The command hangs and I have to use Ctl + c to interrupt it.
docker exec -t …
:# docker exec -t 115c89122e72 bash root@115c89122e72:/# ls ^C
It enters the container successfully but hangs on executing the first command.
So it seems there is no point in having the docker exec -i …
and docker exec -t …
commands. Could anyone elaborate on why there exist -i
and -t
options for the docker exec
command?
-i
, --interactive
keeps STDIN open even if not attached, which you need if you want to type any command at all.
-t
, --tty
Allocates a pseudo-TTY, a pseudo terminal which connects a user's "terminal" with stdin and stdout. (See container/container.go
)
If you do an echo, only -t
is needed.
But for an interactive session where you enter inputs, you need -i
.
Since -i
keeps stdin open, it is also used in order to pipe input to a detached docker container. That would work even with -d
(detach).
See "When would I use --interactive
without --tty
in a Docker container?":
$ echo hello | docker run -i busybox cat
hello
-i
keeps STDIN open even if not attached, what is the status of STDOUT in this case?
It is, for docker exec
, the one set by docker run
.
But, regarding docker exec
, there is a current issue (issue 8755: Docker tty is not a tty with docker exec
unfortunately your discovery only amounts to a difference between the behaviour of tty in centos6 vs ubuntu:14.04. There is still not a functional tty inside the exec - just do
ls -la /proc/self/fd/0
and see that it's a broken link pointing to apts
which doesn't exist.the actual bug we're dealing with is that certain standard libraries assume that the symlinks in /proc/self/fds/ must be valid symlinks
The problem is that the tty is created outside on the host and there is no reference to it in the container like how
/dev/console
is setup in the primary container.
One options to fix this would be allocate and bind mount thedevpts
from the host in to the containers.
Note (Q4 2017): this should been fixed by now (docker 17.06-ce).
See PR 33007.
That PR now allows (since 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
(before 17.06, tty
was returning "not a tty
")
这篇关于"-i"的目的是什么?和"-t" "docker exec"的选项命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!