将tty/std-in-out附加到dockers或lxc是什么意思?

Phi*_*hil 38 docker

我读了一些docker文档,我不明白它可能意味着什么

  • 附上一个tty
  • 附上std-in和std-out

出于这些目的,我看到-i-t使用了标志.

这个过程意味着什么?

Ben*_*ley 36

stdin, stdout, and ttys是相关的概念.stdin并且stdout是进程的输入和输出流.甲伪终端(也称为一个tty或一个pts)用于连接用户的"终端"与stdinstdout通过外壳如流,通常(但不一定)bash.我在"终端"周围使用引号,因为我们今天真的不使用同样意义上的终端.

在泊坞窗的情况下,你会经常使用-t-i在一起的时候,你在交互模式,过程,开始时作为bash外壳.对于shell,您希望能够发出命令并读取输出.

尝试使用stdout/stdinstdin, stdout, and ttys(Docker版本0.8.1)的一些示例:

__PRE__

泊坞窗使用附加代码stdin有所有的肮脏细节.

  • Github链接已死。 (2认同)

lan*_*oxx 13

通过使用该lsof命令,我们可以看到幕后发生的事情.为了演示,我们可以从只运行sleep的Debian映像创建一个简单的docker容器:

docker run -d --name tty-test debian /bin/bash -c "sleep 1000"
Run Code Online (Sandbox Code Playgroud)

这将在一个新容器中启动sleep命令(注意我们没有使用-i-t).

接下来我们通过exec命令"登录"到我们的容器中并启动bash:

docker exec -it tty-test /bin/bash
Run Code Online (Sandbox Code Playgroud)

将无法lsof安装普通的debian映像,因此我们需要安装它:

apt update && apt install -y lsof
Run Code Online (Sandbox Code Playgroud)

接下来我们运行lsof:

lsof
Run Code Online (Sandbox Code Playgroud)

如果没有任何选项运行,lsof将打印所有正在运行的进程的打开文件.您应该在其输出中看到三个进程(sleep,bash和lsof本身).

下面是相关系是那些显示文件描述符(FD列)02.

请注意sleep我们在没有-t选项的情况下启动的进程如何具有三个FIFO管道stdin,stdout并且stderr:

sleep     1 root    0r  FIFO   0,10      0t0 8226490 pipe
sleep     1 root    1w  FIFO   0,10      0t0 8226491 pipe
sleep     1 root    2w  FIFO   0,10      0t0 8226492 pipe
Run Code Online (Sandbox Code Playgroud)

虽然bash过程具有连接到实际装置stdin,stdoutstderr:

bash      7 root    0u   CHR 136,15      0t0      18 /dev/pts/15
bash      7 root    1u   CHR 136,15      0t0      18 /dev/pts/15
bash      7 root    2u   CHR 136,15      0t0      18 /dev/pts/15
Run Code Online (Sandbox Code Playgroud)

让我们使用-t选项创建另一个容器:

docker run -d -t --name tty-test2 debian /bin/bash -c "sleep 1000"
Run Code Online (Sandbox Code Playgroud)

lsof再次安装后(见上文),我们得到了与lsofsleep过程不同的输出:

sleep     1 root    0u   CHR 136,15      0t0      18 /15
sleep     1 root    1u   CHR 136,15      0t0      18 /15
sleep     1 root    2u   CHR 136,15      0t0      18 /15
Run Code Online (Sandbox Code Playgroud)

请注意类型列的更改方式CHR以及名称列的显示方式/15.

最后,当我们-texec命令中省略选项时,如下所示:

docker exec -it tty-test /bin/bash
Run Code Online (Sandbox Code Playgroud)

那么我们可以注意到两件事.首先,我们现在没有从bash获得shell提示符,但我们仍然可以键入命令并查看其输出.当我们运行lsof我们看到bash的过程,现在也有管道而不是连接一个tty来stdin,stdoutstderr

bash    379 root    0r  FIFO   0,10      0t0 8263037 pipe
bash    379 root    1w  FIFO   0,10      0t0 8263038 pipe
bash    379 root    2w  FIFO   0,10      0t0 8263039 pipe
Run Code Online (Sandbox Code Playgroud)

  • 很好的分析。如果您只使用“-t”而不是“-d -t”怎么办?另外,如果将 `--entrypoint` 传递给 `sleep` (无 bash)会怎么样? (2认同)

sha*_*359 6

选项-i -t对于与容器内运行的某些交互式进程(例如 bash shell)进行交互非常有用。

考虑下面的命令

PS C:\Users\nssh> docker run -it ubuntu /bin/bash
root@c7537bbf2941:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64
Run Code Online (Sandbox Code Playgroud)

当我们运行这个命令时,docker 将启动 ubuntu 容器,并在其中运行 bash shell。

  • -i标志告诉 docker 我们输入的任何内容都应该发送到 bash 进程的标准输入。ls上面输入的命令被发送到 bash。

  • -t标志告诉 docker 这将是一个交互式会话,并且标准输入将是一个 tty

对于典型的类似 SSH 的体验,-t 和 -i 必须一起使用。

省略-t的唯一原因是 stdin 是管道(而不是像上面那样的 tty)。当客户端从管道接收标准输入时,禁止指定-t ,如下所示:

PS C:\Users\nssh> echo test | docker run -it ubuntu cat
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'
Run Code Online (Sandbox Code Playgroud)

如果 stdin 是管道,则省略-t标志。

PS C:\Users\nssh> echo test | docker run -i ubuntu cat
test
Run Code Online (Sandbox Code Playgroud)


Rez*_*a S 5

这意味着您可以使用 TTY(即终端)登录到您的容器。就好像您面前有一台 Linux 机器并且您正在登录它。如果您的容器没有运行 SSH 服务器或 telnet,这是进入命令行提示符的唯一模式。

至于为什么-i-t不同的论点我不确定,我无法想象您想使用 TTY 连接但不想要 stdin/stdout 选项或反之亦然的场景。

  • 当您将某些内容通过管道传输到命令中时,省略 tty 标志是有价值的/强制性的。 (3认同)