Moby: docker内部奇怪的终端行为

创建于 2017-06-23  ·  33评论  ·  资料来源: moby/moby

当我在 docker (docker exec -ti container /bin/bash) 中执行到 /bin/bash 并递归搜索命令时,有时终端开始表现得很奇怪,一切都像图片一样混乱。
之后我必须退出容器并再次执行。
selection_017

最有用的评论

我发现这个错误确实是由于终端宽度和高度参数导致的,这些参数有时没有通过 docker exec 命令提供给容器

您可以在此问题中阅读更多相关信息:#10341

我已经通过这种方式解决了这个错误:

docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash

您也可以将此命令放在脚本中并提供容器名称作为参数并创建别名,如 docker-exec

所有33条评论

在我的情况下,Ctrl-P/Ctrl-N 的行为很奇怪,浏览 shell 历史记录很烦人。 我们有可能被同样的问题困扰。

我还注意到,使用向上键浏览历史有时会重现这种行为。

我经常遇到终端问题,这些问题似乎归结为 Docker 没有弄清楚最初的正确终端大小是多少。 这似乎只发生在新的终端上。 (这可能是也可能不是导致您出现问题的原因。)例如:

$ docker exec -it foo /bin/bash
foo<strong i="6">@649fb21d747c</strong>:~$ stty size
0 0
foo<strong i="7">@649fb21d747c</strong>:~$ reset -w
foo<strong i="8">@649fb21d747c</strong>:~$ stty size
24 80
foo<strong i="9">@649fb21d747c</strong>:~$ # That was still wrong. Now resize the terminal to get a SIGWINCH.
foo<strong i="10">@649fb21d747c</strong>:~$ stty size
69 208
foo<strong i="11">@649fb21d747c</strong>:~$ exit
exit
$ docker exec -it foo /bin/bash # Try it again.
foo<strong i="12">@649fb21d747c</strong>:~$ stty size
69 208
foo<strong i="13">@649fb21d747c</strong>:~$ # Doesn't happen anymore for this session.

我发现这个错误确实是由于终端宽度和高度参数导致的,这些参数有时没有通过 docker exec 命令提供给容器

您可以在此问题中阅读更多相关信息:#10341

我已经通过这种方式解决了这个错误:

docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash

您也可以将此命令放在脚本中并提供容器名称作为参数并创建别名,如 docker-exec

谢谢@cromat! 这解决了我在 Windows 上的 Bash 中使用 Docker for Windows 时的问题,由于没有正确的 TTY,输出不够宽。 看起来你的反引号被格式化为代码,所以这里又是一行:

docker exec -t container_name /bin/bash -c "export COLUMNS=`tput cols`; export LINES=`tput lines`; exec bash"

对于来这里寻找答案的任何人,您可以在 stackoverflow 上找到它

谢谢@PhilT。

这对我有用。

docker exec -it container_name sh -c "stty rows 50 && stty cols 150 && bash"

谢谢! 这也解决了我的!

在尝试了十几种解决方案后, @PhilT是唯一有效的解决方案

这是更正确的做法。 不需要双重执行 bash。

docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash

@eigood的解决方案在第一次尝试时就像魅力一样......

我将 ubuntu 与 gnome 一起使用。 通常我会调整窗口大小,问题会自行解决。
在 gnome 中调整大小是Ctrl+Super+(Down Arrow)然后是Ctrl+Super+(Up Arrow)

@eigood感谢您提供正确的解决方案。 为什么 Docker 不这样做呢?

@PhilT @cromat在我的情况下,我确实需要-i选项,如-it而不仅仅是-t选项。

我创建了一个别名,让我的生活更轻松。

alias dexec='docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti $1'

例如。:

dexec containername_service_1 bash

@romulo1984你在运行什么版本的

@thaJeztah 17.12.0-ce

该版本于 3 月停产; 我建议更新到 18.06(当前稳定版本),它有这个修复

@thaJeztah谢谢。

我可以确认此问题已通过 Docker 18.06 解决。

@nodakai我和你有同样的问题:我没有宽度或任何问题,但 Docker 某些东西不会重绘。 具体来说,如果我使用 ctrl-p 和 ctrl-n 滚动浏览 bash 历史记录(这是我的习惯),它不会重绘。 如果我使用箭头键,它会。

您是否设法找到解决此问题的方法?

@Grazfather我认为这是一个不同的问题。 我认为问题在于从容器中分离的关键序列是C-p C-q ,因此 docker 看到您的C-p并且正在等待C-q以便分离。 我还没有真正尝试过,但使用--detach-keys=可能会有所帮助。

对于来这里寻找答案的任何人,您可以在 stackoverflow 上找到它

链接到这里的答案是最好的解决方案 imo 因为当您在容器内切换用户时,其他解决方案不起作用,假设您想要新用户的环境,它将覆盖 LINES 和 COLUMNS 环境变量。

我在 docker 中使用 xshell exec ..

image

当我调整 xshell 窗口的大小时...
image

exec tty size 正确重置...任何人都知道这是为什么,以及 xshell 是如何做到的...我在较低的 docker 版本上工作

image

解决这个问题的Docker-compose示例:

version: '3'
services:
    php:
        container_name: cmg-php
        hostname: "docker-stand"
        build:
            context: ./
        environment:
            - COLUMNS=`tput cols`
            - LINES=`tput lines`

注重环境。 @cromat谢谢!

@frops您的解决方案无效。 environment键用于在创建容器步骤初始化环境,因此它不是正确的解决方案。 您需要在容器输入期间设置 env 值,而不是创建。

此外,正如我读到的@thaJeztah说它已在 18.06 中修复

肯定应该在 18.06 及更高版本中得到改进,但仍有一些情况可能需要重新触发调整大小(您可以通过调整终端窗口的大小来实现); 有一个 pull request 为这些情况添加了一个重试循环,但它尚未合并; https://github.com/docker/cli/pull/1529

我会考虑为某些情况设置COLUMNSLINES一种解决方法,但不能保留在您的环境中

我发现如果使用--tty而没有--interactive运行,该错误仍然存​​在。
Docker 版本 18.09.2,内部版本 6247962

重现示例:

FROM debian
RUN apt-get update
RUN apt-get install -y sl
CMD /usr/games/sl

输出损坏/终端大小错误的命令:
docker run --rm --tty slimage

https://github.com/docker/cli/pull/1529尚未在`Docker 18.09 中

预计将于 19.03.0(2019 年 7 月 10 日)修复

它通过https://github.com/docker/cli/pull/1775重新移植到 Docker CLI 18.09.5

使用以下命令编译 openwrt 时,仍然出现在最新的 Mac OS 中:
制作菜单配置
并且所有上述解决方法都不适用于混乱的 ncurses 窗口

docker version

    Client: Docker Engine - Community
     Version:           19.03.1
     API version:       1.40
     Go version:        go1.12.5
     Git commit:        74b1e89
     Built:             Thu Jul 25 21:18:17 2019
     OS/Arch:           darwin/amd64
     Experimental:      false

    Server: Docker Engine - Community
     Engine:
      Version:          19.03.1
      API version:      1.40 (minimum version 1.12)
      Go version:       go1.12.5
      Git commit:       74b1e89
      Built:            Thu Jul 25 21:17:52 2019
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          v1.2.6
      GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
     runc:
      Version:          1.0.0-rc8
      GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
     docker-init:
      Version:          0.18.0
      GitCommit:        fec3683
docker version

    Client: Docker Engine - Community
     Version:           19.03.1
     API version:       1.40
     Go version:        go1.12.5
     Git commit:        74b1e89
     Built:             Thu Jul 25 21:18:17 2019
     OS/Arch:           darwin/amd64
     Experimental:      false

    Server: Docker Engine - Community
     Engine:
      Version:          19.03.1
      API version:      1.40 (minimum version 1.12)
      Go version:       go1.12.5
      Git commit:       74b1e89
      Built:            Thu Jul 25 21:17:52 2019
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          v1.2.6
      GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
     runc:
      Version:          1.0.0-rc8
      GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
     docker-init:
      Version:          0.18.0
      GitCommit:        fec3683

我为自己制作了一个便携式 VIM 配置,其中包含所有用于样式和 linting/修复的精美插件。 在我提出@cromat解决方案之前,我总是遇到 VIM + NERDTree 的布局问题。 现在它运作良好。 只是给自己取了一个别名(函数,我喜欢函数,但这里也一样)。

$ vi ~/.zshrc
function vim {
    docker run --env LINES=$(tput lines) --env COLUMNS=$(tput cols) # ... 
}
此页面是否有帮助?
0 / 5 - 0 等级