这是一个有效的命令:
$ echo 'hi there' | docker run -i ubuntu cat
hi there
这是一个用错误消息响应的命令:
$ echo 'hi there' | docker run -it ubuntu cat
the input device is not a TTY
我想弄清楚这里到底发生了什么。不仅仅是“删除-t,它就会被修复”。
我知道docker run
的S -t
选项代表“分配一个伪TTY”,我也读过TTY所代表的历史概况,但它并没有帮助我理解这里违反了什么样的合同。
发布于 2018-02-19 15:49:45
发布于 2019-01-18 12:52:41
迟答,但可能对某人有帮助
docker run/exec -i
将把容器内命令的STDIN连接到docker run/exec
本身的STDIN。
所以
docker run -i alpine cat
给您一个空行等待输入。输入"hello“--你会得到回音"hello”。容器在发送CTRL+D之前不会退出,因为主进程cat
正在等待来自无限流(即docker run
的终端输入)的输入。echo "hello" | docker run -i alpine cat
将打印"hello“并立即退出,因为cat
注意到输入流已经结束并终止了自己。如果在退出上述任何一个之后尝试docker ps
,您将找不到任何正在运行的容器。在这两种情况下,cat
本身都已经终止,因此停靠器已经终止了容器。
现在对于"-t",这告诉对接器内部的主进程,它的输入是一个终端设备。
所以
docker run -t alpine cat
会给你一个空行,但是如果你尝试输入"hello",你就不会得到任何回显。这是因为当cat
连接到终端输入时,这个输入没有连接到您的输入。您输入的"hello“没有到达cat
的输入。cat
正在等待从未到达的输入。echo "hello" | docker run -t alpine cat
也会给您一个空行,不会退出CTRL-D上的容器,但是您不会得到回显"hello“,因为您没有通过-i
。如果您发送CTRL+C,您将得到您的shell,但是如果现在尝试docker ps
,您将看到cat
容器仍然在运行。这是因为cat
仍然在等待一个从未关闭的输入流。我还没有发现单独使用-t
而不与-i
相结合的任何有用之处。
现在,为了-it
在一起。这告诉猫它的输入是一个终端,同时将这个终端连接到终端docker run
的输入端。docker run/exec
将确保它自己的输入在传递给cat
之前实际上是个tty。这就是如果您尝试使用input device is not a TTY
时将得到echo "hello" | docker run -it alpine cat
的原因,因为在本例中,docker run
本身的输入是来自上一个回波的管道,而不是执行docker run
的终端。
最后,如果-t
能够将您的输入连接到cat
的S输入,那么为什么需要通过-i
呢?这是因为如果输入是终端,命令对输入的处理就会不同。
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
会给你一个密码提示。如果键入密码,字符就会明显打印出来。docker run -i alpine sh
会给你一个空行。如果键入像ls
这样的命令,就会得到输出,但不会得到提示符或彩色输出。在最后两种情况下,您会得到这种行为,因为mysql
和shell
都没有将输入作为tty来处理,因此没有使用tty特定的行为,比如掩蔽输入或着色输出。
发布于 2018-02-19 12:56:28
tty表示您有一个终端,它将由xterm或许多linux命令行接口中的一个提供。它需要一个与之相关联的键盘和文本输出接口。想要这样做的典型原因是支持彩色文本输出,处理各种键组合(如箭头键),以及在屏幕周围移动光标的能力。
当您将命令管道输送到停靠程序中时,如您的echo
示例所示,该管道是输入,而该管道没有tty接口,它只是一个文本流。试图创建一个tty将失败,正如错误消息所指示的那样。
https://serverfault.com/questions/897847
复制相似问题