当前位置: 首页 > 知识库问答 >
问题:

对Docker-t选项分配伪TTY感到困惑

施飞雨
2023-03-14

这个选项到底有什么作用?我读了很多关于TTY的书,但我还是很困惑。我在没有-t的情况下到处玩,只玩-I,而且似乎期望用户输入的程序在没有-t的情况下抛出错误。为什么启用伪TTY很重要?

共有3个答案

岳正阳
2023-03-14

根据谷歌搜索,-t参数没有很好地记录下来,或者很多人经常提到。

当您在Bash提示符下键入docker来显示(应该是什么)所有docker客户端参数的列表时,它甚至不会显示出来(最新版本为1.8.1)。

事实上,如果您试图通过键入docker-t--help来获得有关此参数的具体帮助,if会给出一个非常模糊的回答:

已提供但未定义的标志:-t

所以,你不能因为对这个论点感到困惑而受到责备!

Docker在线文档中提到它是“分配一个伪tty”,通常与-i一起使用:

https://docs.docker.com/reference/run/

我看到它用在jwilder/nginx-代理docker容器的留档中,方式如下:

docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx

在本例中,它所做的是将输出发送到此docker容器中的“virtual”tty(Bash命令提示符/终端)。然后,您可以通过运行docker命令docker logs CONTAINER查看此输出,其中CONTAINER是此容器ID的前两个字符。可以通过键入docker ps-a

我已经在下面的链接中看到了这个-t参数,它说

-t-i标志分配一个伪tty,即使未连接,也保持stdin打开。这将允许您像传统VM一样使用容器,只要bash提示符正在运行。

https://coreos.com/os/docs/latest/getting-started-with-docker.html

我希望这有帮助!我不知道为什么这没有被记录或使用的太多。也许它是实验性的,并将在即将发布的版本中作为一个文档化的特性来实现。

葛子昂
2023-03-14

迟来的回答,但可能会对某人有所帮助

docker run/exec-i将容器内命令的STDIN连接到docker run/exec本身的STDIN。

所以呢

  • docker run-i alpine cat为您提供一条等待输入的空行。输入“hello”,你会收到一个回音“hello”。在您发送CTRLD之前,容器不会退出,因为主进程cat正在等待来自无限流的输入,该无限流是docker运行的终端输入
  • 另一方面,echo“hello”| docker run-i alpine cat将打印“hello”并立即退出,因为cat注意到输入流已结束并自行终止

如果在退出上述任一项后尝试docker ps,将找不到任何正在运行的容器。在这两种情况下,cat本身已终止,因此docker已终止容器。

现在对于"-t",它告诉docker中的主进程它的输入是一个终端设备。

所以呢

  • docker run-t alpine cat将给您一条空行,但如果您尝试键入“hello”,您将不会收到任何回音。这是因为当cat连接到终端输入时,该输入未连接到您的输入。您键入的“hello”未到达cat的输入cat正在等待从未到达的输入

如果您发送CTRLC,您将获得shell,但是如果您现在尝试docker ps,您将看到cat容器仍在运行。这是因为cat仍在等待从未关闭的输入流。如果不与-I结合使用,我没有发现-t单独使用有任何用处。

现在,对于-它将放在一起。这告诉cat其输入是一个终端,同时将此终端连接到作为终端的docker run的输入docker run/exec将确保它自己的输入实际上是一个tty,然后再将其传递给cat。这就是为什么如果您尝试echo“hello”| docker run,您会得到一个输入设备不是TTY,因为在这种情况下,docker run本身的输入是来自上一个echo的管道,而不是执行docker run的终端

最后,如果-i能够将您的输入连接到cat的输入,您为什么需要传递-t?这是因为如果输入是终端,则命令会以不同的方式处理输入。这也是最好的例子说明

  • docker run-e MYSQL\u ROOT\u PASSWORD=123-i mariadb MYSQL-u ROOT-p会给你一个密码提示。如果键入密码,字符将以可见方式打印

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

汤乐家
2023-03-14

-t选项用于说明Unix/Linux如何处理终端访问。过去,终端是硬线连接,后来是基于调制解调器的连接。它们有物理设备驱动程序(它们是真正的设备)。一旦通用网络开始使用,就开发了一个伪终端驱动程序。这是因为它在理解可以使用哪些终端功能而无需直接将其写入程序(阅读sttycurses上的手册页)之间建立了一种分离。

所以,以它为背景,运行一个没有选项的容器,默认情况下,你有一个stdout流(所以docker run|

 类似资料:
  • 这个选项到底有什么作用?我读了很多关于TTY的书,但我还是很困惑。我在没有的情况下到处玩,只玩,而且似乎期望用户输入的程序在没有的情况下抛出错误。为什么启用伪TTY很重要?

  • 我正在尝试提出一种解决方案,它涉及在连接操作之后应用一些逻辑,从多个中的中选择一个事件。这类似于reduce函数,但它只返回1个元素,而不是递增地返回。因此最终结果将是单个(,对,而不是一个 每个键保证只到达一次。 假设像上面这样的连接操作,它用4个生成了1个,成功地连接并收集在。现在,我想做的是,立即访问这些值,并执行一些逻辑以将正确匹配到一个。例如,对于上面的数据集,我需要(,和)。 将为每个

  • 所以我一直在读Kafka的语义学,我对它的工作原理有点困惑。 我理解生产者如何避免发送重复的消息(以防代理的ack失败),但我不明白的是,在消费者处理消息但在提交偏移量之前崩溃的情况下,一次是如何工作的。Kafka不会在这种情况下重试吗?

  • 问题内容: 我正在尝试使用Paramiko连接到远程主机并执行许多文本文件替换。 其中一些命令需要作为sudo运行,从而导致: sudo:对不起,您必须有一个tty才能运行sudo 我可以使用-t开关和ssh强制进行伪tty分配。 使用paramiko可以做同样的事情吗? 问题答案: 我认为您想要对象的方法(我想提供一个URL,但是lag.net上的paramiko文档非常繁琐,只是不会为我显示文

  • 问题内容: 我已经在eclipse中创建了一个项目,并添加了Maven依赖项。在Eclipse中,它表示我正在使用JRE 1.5。一切在Eclipse中都可以正常运行,例如,我可以运行测试。 当我尝试从终端运行时,出现以下错误。 …在-source 1.3中不支持泛型(使用-source 5或更高版本来启用泛型)… 看来,Maven认为我正在使用JRE 1.3,并且无法识别泛型或for-each循

  • 问题内容: 在碰到此链接http://www.javacodegeeks.com/2013/01/java-thread-pool-example-using- executors-and-threadpoolexecutor 之后,这是我第一次为新项目使用Java线程池。 .html ,我对此更加困惑,这是页面中的代码, 在代码中,创建了一个固定大小的池并创建了10个工作线程,对吗? 线程池应该