我阅读了一些Docker文档,但是不理解以下术语的含义:
- 附加TTY
- 附加标准输入和输出
为了达到这些目的,我看到使用了-i
和-t
标志。
这个过程是什么意思呢?
我阅读了一些Docker文档,但是不理解以下术语的含义:
为了达到这些目的,我看到使用了-i
和-t
标志。
这个过程是什么意思呢?
stdin
、stdout
和ttys是相关的概念。 stdin
和stdout
是进程的输入和输出流。伪终端(也称为tty
或pts
)通过一个shell(例如bash
),通常(但不一定)连接用户的“终端”与stdin
和stdout
流。我在“终端”周围使用引号,因为我们今天并不像以前那样使用终端。
在docker的情况下,当您以交互模式运行进程时,例如启动bash
shell时,您经常会同时使用-t
和-i
。在shell的情况下,您希望能够发出命令并读取输出。
docker用于附加stdout/stdin
的代码具有所有详细信息。
lsof
命令来查看底层发生了什么。为了进行演示,我们可以从Debian镜像创建一个简单的Docker容器,只运行sleep命令:docker run -d --name tty-test debian /bin/bash -c "sleep 1000"
exec
命令“登录”到容器中,并启动bash:docker exec -it tty-test /bin/bash
一个纯净的Debian镜像中没有安装lsof
,因此我们需要安装它:
apt update && apt install -y lsof
接下来我们运行lsof命令:
lsof
lsof
将打印所有正在运行的进程的打开文件。您应该在其输出中看到三个进程(sleep、bash和lsof本身)。0
到2
的行。sleep
进程有三个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
虽然 bash
进程实际上连接了一个设备到 stdin
、stdout
和 stderr
:
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
-t
选项创建另一个容器:docker run -d -t --name tty-test2 debian /bin/bash -c "sleep 1000"
lsof
后(见上文),我们可以得到sleep
进程的不同输出: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
CHR
,名称列显示/15
。exec
命令中省略-t
选项时,就像这样:docker exec -it tty-test /bin/bash
那么我们可以注意到两件事情。首先,现在我们无法从bash中得到shell提示符,但我们仍然可以输入命令并查看它们的输出。当我们运行lsof
时,我们可以看到bash
进程现在也有管道而不是附加到stdin
、stdout
和stderr
的tty。
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
-i
和 -t
是不同的参数,我不确定,我无法想象出一种情况,在这种情况下,您希望使用 TTY 连接而不想使用 stdin/stdout 选项或反之亦然。ssh-keygen
这样的程序,我相信你不需要 -t
标志。类似 docker run -i ubuntu /usr/bin/ssh-keygen ...
的命令即可。 - Uri选项-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
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'
如果 stdin 是管道,请省略 -t 标志。
PS C:\Users\nssh> echo test | docker run -i ubuntu cat
test
简单来说,它允许我们连接和断开容器的终端。要连接,我们使用docker attach命令,要断开,我们使用CTRL+P & CTRL+Q命令。