"-i"的目的是什么?和"-t" "docker exec"的选项命令? [英] What is the purpose of the "-i" and "-t" options for the "docker exec" command?

查看:118
本文介绍了"-i"的目的是什么?和"-t" "docker exec"的选项命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  1. 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
    

    它正常工作.

  2. docker exec -i …:

    # docker exec -i 115c89122e72 bash
    ^C
    

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

  3. 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.

不幸的是,您的发现仅相当于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:

  1. 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.

  2. docker exec -i …:

    # docker exec -i 115c89122e72 bash
    ^C
    

    The command hangs and I have to use Ctl + c to interrupt it.

  3. 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 a pts 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 the devpts 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆