“docker run”输出中的“输入设备不是TTY”到底是什么意思?

“docker run”输出中的“输入设备不是TTY”到底是什么意思?

这是一个有效的命令:

$ 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选项-t代表“分配伪 TTY”,并且我已经阅读TTY 的历史概述,但它并没有帮助我了解这里违反了什么样的合同。

答案1

回答较晚,但可能会对某人有帮助

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如果您在退出上述任一操作后尝试,您将找不到任何正在运行的容器。在这两种情况下, catdocker 本身都已终止,因此 docker 已终止容器。

现在对于“-t”,这告诉docker内部的主进程它的输入是一个终端设备。

所以

  • docker run -t alpine cat会返回一个空行,但如果您尝试输入“hello”,则不会得到任何回显。这是因为虽然cat连接到终端输入,但此输入未连接到您的输入。您输入的“hello”未到达 的输入catcat正在等待永远不会到达的输入。
  • echo "hello" | docker run -t alpine cat也会给你一个空行,并且不会在 CTRL-D 上退出容器,但你不会得到回显“hello”,因为你没有通过-i

如果您发送 CTRL+C,您将恢复 shell,但如果您docker ps现在尝试,您会看到cat容器仍在运行。这是因为cat仍在等待从未关闭的输入流。我发现 单独使用-t而不与 结合使用没有任何有用的用途-i

现在,将-it合并起来。这告诉 cat 它的输入是一个终端,同时将此终端连接到 的输入, 的输入docker run是一个终端。docker run/exec在将其传递给 之前,将确保其自身的输入实际上是一个 tty cat。这就是为什么input device is not a TTY如果您尝试,您将得到一个echo "hello" | docker run -it alpine cat,因为在这种情况下, 的输入本身是来自上一个 echo 的管道,而不是执行的docker run终端docker run

最后,为什么你需要传递-tif-i来完成将你的输入连接到 的输入的技巧cat?这是因为如果输入是终端,命令会以不同的方式处理输入。这也最好通过示例来说明

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p将提示您输入密码。如果您输入密码,则会打印出字符。
  • docker run -i alpine sh将返回一个空行。如果您键入类似命令,ls则会获得输出,但不会获得提示或彩色输出。

在最后两种情况下,您会得到这种行为,因为mysql以及shell没有将输入视为 tty,因此没有使用 tty 特定的行为,例如屏蔽输入或为输出着色。

答案2

这个答案帮助我理解:

  • 默认情况下(没有-i-t选项),Docker 容器仅将其输出发送到 STDOUT,
  • 带有-i连接到 STDIN 的选项,
  • -t选项引入终端接口驱动程序,在 STDIN/STDOUT 上运行。当引入终端驱动程序时,与容器的通信必须符合终端接口协议. 管道字符串则不然。

答案3

tty 表示您有一个终端,这是 xterm 或众多 linux 命令行界面之一提供的功能。它需要与之关联的键盘和文本输出界面。需要它的典型原因是支持彩色文本输出、处理各种组合键(如箭头键)以及能够在屏幕上移动光标。

当您将命令通过管道传输到 docker 中(如您的echo示例所示),该管道就是输入,并且该管道没有 tty 接口,它只是一个文本流。尝试用它创建 tty 将失败,如错误消息所示。

相关内容