Docker在Docker中更改的行数

我想知道如何改变以下行为。 假设我的terminal有28行。 然后我使用下面的命令:

$ tput lines # my terminal 28 $ docker run --rm -it ubuntu:16.04 tput lines # docker container 24 ## WHY?? $ docker run --rm -it ubuntu:16.04 bash # docker container inside command root@810effa2777c:/# tput lines 28 

正如你所看到的,即使所有的结果应该是28 ,当我打电话给docker run --rm -it ubuntu:16.04 tput lines的容器docker run --rm -it ubuntu:16.04 tput lines它总是给我24,尽pipe我的terminal的大小。 这不仅与Ubuntu的容器,我也尝试与debian( docker run --rm -it debian tput lines ),我有同样的结果24。

这样做的目的是使用mdp演示工具 ,它考虑到terminal中的行。 当我的实现失败时,我尝试了一些其他人的docker执行,但我跑到相同的错误。

这是我在图像中的错误:

Docker在Docker中更改的行数

有没有人有任何想法可以解决这个问题?

Ubuntu Dockerfile包括:

 CMD ["/bin/bash"] 

这意味着默认的ENTRYPOINTsh -c (并且我怀疑tput linesh会话中工作正常,因为tput使用的是terminfo数据库,它可能只为该映像中的bash设置)

你可以尝试用bash -c覆盖ENTRYPOINT ,并检查它是否工作得更好。

这不从命令行工作,但:

 docker run --entrypoint /bin/bash --rm -it ubuntu:16.04 -i -c 'tput lines' 24 

我将检查定义自定义图像的选项。

 FROM ubuntu:16.04 ENTRYPOINT ["/bin/bash", "-c"] 

结果是一样的:

 docker run --rm -it u 'tput lines' 24 

然而这“工作”:

 FROM ubuntu:16.04 ENTRYPOINT [ "/bin/bash" ] 

附:

 docker@default:/c/Users/vonc/prog/testsu$ docker run --rm -it u -i -c 'ls; tput lines' bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var 48 

可能会有同步问题,因为同一个命令不时会返回24。

其实,下面总是回复“不是24”:

 FROM ubuntu:16.04 ENTRYPOINT [ "/bin/bash", "-l", "-i", "-c" ] docker run --rm -it u -c 'sleep 0.1; ls; tput lines' 48 

OP silgon 在评论中提出 :

 docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines" 

正如下面的 BMitch所评论的:

考虑到睡眠的成功,我怀疑docker是用运行命令来启动容器,一旦启动,客户端就会连接到正在运行的容器。 通常需要几毫秒。

这给了我另一个想法:

 docker@default:/c/Users/vonc/prog/testsu$ docker run --entrypoint='/bin/bash' --name ub -d -it ubuntu:16.04 0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b docker@default:/c/Users/vonc/prog/testsu$ d attach ub root@0d9b8783afbb:/# tput lines 48 root@0d9b8783afbb:/# exit exit docker@default:/c/Users/vonc/prog/testsu$ drmae 0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b 

附加会话中的inputtput lines很好。
(关于drmae别名,请参阅“ 如何删除旧的和未使用的Docker镜像 ”)


thajeztah补充说 :

容器被创build,然后以默认值( 80x24 )开始,然后( 80x24 ),连接一个会话。
会话正在指定terminal的大小;

请参阅“ 调整容器TTY ”API。

  DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee4‌​3a/resize?h=46&w=221 

有关更多信息,请参阅docker issue 25450 。
它与问题10341“容器创build或启动应接受高度/宽度参数”有关 。 Aleksa Sarai(cyphar)增加( 2016年9月 ):

这实际上已经在运行时规范( opencontainers / runtime-spec PR 563 )中popup了。
基本上,由于Windows要求能够在首次启动时设置控制台大小,因此我们最终可能会将其添加到所有平台


OP silgon指出了api/client/container/run.go

 // Telling the Windows daemon the initial size of the tty during start makes // a far better user experience rather than relying on subsequent resizes // to cause things to catch up. if runtime.GOOS == "windows" { hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCli.GetTtySize() } 

有了合乎逻辑的问题:

在Linux上使用这个属性是否有意义,并使用该值设置初始控制台大小?

Kenfe-MickaëlLaventure( mlaventure )就在这上面,而且一个新的补丁可以让它成为Docker 1.13 。

关于sh和terminfo的评论在很大程度上是不相关的。 相关的部分(在给定的答案中不清楚)是命令执行的方式。 tput按以下顺序(使用setupterm )检查三个function:

  1. 从terminfo数据库的terminal的大小(许多描述不给这个信息,但与TERM=xterm ,它是2480 ),
  2. 如果可以从操作系统获得该信息(即当前窗口大小 )的实际行数,以及
  3. LINESCOLUMNS环境variables。

在没有交互式shell的情况下运行的命令可以以不能获得当前窗口大小的方式执行。 例如,这是ssh一个function( -t选项)。 另外,Docker可能(虽然毫无意义)设置LINESCOLUMNSvariables。

案例(1)或(3)足以解释行为; 引入时间延迟和比赛不这样做。