这个选项到底有什么作用?我读了很多关于TTY的文章,但我还是很困惑。我没有使用-t,只使用-i,看起来程序需要用户输入而不使用-t就会抛出错误。为什么启用伪tty很重要?
当前回答
回答晚了,但也许能帮到别人
docker run/exec -i将容器内命令的STDIN连接到docker run/exec本身的STDIN。
So
Docker run -i alpine cat为您提供一个等待输入的空行。输入“hello”,你会得到一个回音“hello”。容器在发送CTRL+D之前不会退出,因为主进程cat正在等待来自无限流的输入,无限流是docker运行的终端输入。 另一方面,echo "hello" | docker run -i alpine cat将输出"hello"并立即退出,因为cat注意到输入流已经结束并终止了自己。
如果您在退出上述任何一个后尝试docker ps,您将找不到任何正在运行的容器。在这两种情况下,cat本身已经终止,因此docker也终止了容器。
现在对于"-t",它告诉docker内部的主进程它的输入是一个终端设备。
So
Docker run -t alpine cat会给你一个空行,但是如果你尝试输入“hello”,你不会得到任何回显。这是因为当cat连接到一个终端输入时,这个输入并没有连接到你的输入。你输入的“hello”没有到达cat的输入。Cat正在等待永远不会到达的输入。 echo "hello" | docker run -t alpine cat也会给你一个空行,并且不会在CTRL-D上退出容器,但你不会得到一个echo "hello",因为你没有传递-i
如果你发送CTRL+C,你会得到你的shell,但如果你现在尝试docker ps,你会看到cat容器仍然在运行。这是因为cat仍然在等待一个从未关闭的输入流。我还没有发现单独使用-t而不与-i结合的任何有用用途。
现在,一起来。这告诉cat它的输入是一个终端,同时将这个终端连接到docker run的输入,这是一个终端。Docker run/exec将确保它自己的输入在传递给cat之前实际上是tty。这就是为什么如果你尝试echo "hello" | docker run -it alpine cat,你会得到一个输入设备不是TTY的原因,因为在这种情况下,docker run本身的输入是来自前一个echo的管道,而不是执行docker run的终端
最后,如果-i将把你的输入连接到cat的输入,为什么你需要传递-t呢?这是因为如果输入是终端,命令对输入的处理是不同的。这也可以用例子来说明
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -u root -p将提示密码。如果您键入密码,则会显示字符。 Docker run -i alpine sh会给你一个空行。如果您键入像ls这样的命令,则会得到一个输出,但不会得到提示符或彩色输出。
在最后两种情况下,你会得到这种行为,因为mysql和shell没有将输入作为tty处理,因此没有使用特定的tty行为,如屏蔽输入或输出着色。
其他回答
-it组合选项称为交互模式。
默认情况下,容器只有一个标准输出流(即docker run | CMD works),要与我们的容器交互,我们需要以下两个选项:
-i添加一个stdin流(即CMD | docker run works); -t分配一个伪tty主/从对,从部分绑定到容器中正在运行的进程,主部分绑定到docker命令。
stdin流将容器附加到您的shell的stdin流(docker继承了您的shell的stdin流),而TTY行规程使您能够以键盘方式与容器交互。
TTY行规程由内核提供给TTY设备的低级特性组成,例如编辑缓冲区和基本的行编辑命令。
如下所示,您可以使用以下命令检查标准文件描述符:
docker run --rm -i ubuntu sh -c "ls -l /proc/\$\$/fd"
如果你移除-i,你会看到stdin指向/dev/null(也就是说,没有分配流)。
回答晚了,但也许能帮到别人
docker run/exec -i将容器内命令的STDIN连接到docker run/exec本身的STDIN。
So
Docker run -i alpine cat为您提供一个等待输入的空行。输入“hello”,你会得到一个回音“hello”。容器在发送CTRL+D之前不会退出,因为主进程cat正在等待来自无限流的输入,无限流是docker运行的终端输入。 另一方面,echo "hello" | docker run -i alpine cat将输出"hello"并立即退出,因为cat注意到输入流已经结束并终止了自己。
如果您在退出上述任何一个后尝试docker ps,您将找不到任何正在运行的容器。在这两种情况下,cat本身已经终止,因此docker也终止了容器。
现在对于"-t",它告诉docker内部的主进程它的输入是一个终端设备。
So
Docker run -t alpine cat会给你一个空行,但是如果你尝试输入“hello”,你不会得到任何回显。这是因为当cat连接到一个终端输入时,这个输入并没有连接到你的输入。你输入的“hello”没有到达cat的输入。Cat正在等待永远不会到达的输入。 echo "hello" | docker run -t alpine cat也会给你一个空行,并且不会在CTRL-D上退出容器,但你不会得到一个echo "hello",因为你没有传递-i
如果你发送CTRL+C,你会得到你的shell,但如果你现在尝试docker ps,你会看到cat容器仍然在运行。这是因为cat仍然在等待一个从未关闭的输入流。我还没有发现单独使用-t而不与-i结合的任何有用用途。
现在,一起来。这告诉cat它的输入是一个终端,同时将这个终端连接到docker run的输入,这是一个终端。Docker run/exec将确保它自己的输入在传递给cat之前实际上是tty。这就是为什么如果你尝试echo "hello" | docker run -it alpine cat,你会得到一个输入设备不是TTY的原因,因为在这种情况下,docker run本身的输入是来自前一个echo的管道,而不是执行docker run的终端
最后,如果-i将把你的输入连接到cat的输入,为什么你需要传递-t呢?这是因为如果输入是终端,命令对输入的处理是不同的。这也可以用例子来说明
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -u root -p将提示密码。如果您键入密码,则会显示字符。 Docker run -i alpine sh会给你一个空行。如果您键入像ls这样的命令,则会得到一个输出,但不会得到提示符或彩色输出。
在最后两种情况下,你会得到这种行为,因为mysql和shell没有将输入作为tty处理,因此没有使用特定的tty行为,如屏蔽输入或输出着色。
-it指示Docker分配一个伪tty连接到容器的stdin,在容器中创建一个交互式bash shell。
——interactive, -i false保持STDIN打开,即使没有附加
——tty, -t false分配一个伪tty
https://docs.docker.com/engine/reference/commandline/run/
我对-t的了解如下:
docker exec -ti CONTAINER bash允许我在容器中“登录”。感觉像嘘嘘(其实不是)。
但问题是当我想恢复数据库时。
通常我dodocker exec -ti mysql.5.7 mysql -这里我在容器中执行mysql命令并获得一个交互式终端。
我添加了<dump。sql到前面的命令,以便我可以恢复一个db。但是它失败了,不能在非tty输入上启用tty模式。
删除-t会有所帮助。还是不明白为什么:
docker exec -i mysql.5.7 mysql < dump.sql
最后一个可行。希望这能帮助到人们。
Docker在线文档中提到它是“分配一个伪tty”,经常与-i一起使用:
https://docs.docker.com/reference/run/
我在jwilder/nginx-proxy docker容器的文档中看到它是这样使用的:
docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
在这种情况下,它所做的是将输出发送到docker容器中的“虚拟”tty (Bash命令提示符/终端)。然后,您可以通过运行docker命令docker logs CONTAINER查看此输出,其中CONTAINER是容器ID的前两个字符。这个CONTAINER ID可以通过输入docker ps -a找到
我在下面的链接中看到了这个-t参数,它说
-t和-i标志分配一个伪tty并保持stdin打开 如果没有附上。这将允许您使用容器像 只要bash提示符在运行。
https://coreos.com/os/docs/latest/getting-started-with-docker.html
推荐文章
- 如何在docker映像的新容器中运行bash ?
- docker -撰写持久数据MySQL
- 从主机连接到docker容器中的mysql
- 当我使用Alpine作为基本图像时,如何添加用户?
- Docker -绑定0.0.0.0:4000失败:端口已经分配
- 将Python诗歌与Docker集成
- 如何在系统启动时运行docker-compose up -d ?
- 如何确定一个进程是否运行在lxc/Docker内部?
- 在docker容器上挂载多个卷?
- Kubernetes如何使部署更新映像
- Docker-compose up vs Docker-compose up -build vs Docker-compose build -no-cache
- 在Docker Alpine容器中启动一个shell
- 允许docker容器连接到本地/主机postgres数据库
- 在Docker Desktop中定位数据卷(Windows)
- 如何通过docker运行传递参数到Shell脚本