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执行,但我跑到相同的错误。
这是我在图像中的错误:
有没有人有任何想法可以解决这个问题?
Ubuntu Dockerfile包括:
CMD ["/bin/bash"]
这意味着默认的ENTRYPOINT
是sh -c
(并且我怀疑tput line
在sh
会话中工作正常,因为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/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee43a/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:
- 从terminfo数据库的terminal的大小(许多描述不给这个信息,但与
TERM=xterm
,它是24乘80 ), - 如果可以从操作系统获得该信息(即当前窗口大小 )的实际行数,以及
-
LINES
和COLUMNS
环境variables。
在没有交互式shell的情况下运行的命令可以以不能获得当前窗口大小的方式执行。 例如,这是ssh
一个function( -t
选项)。 另外,Docker可能(虽然毫无意义)设置LINES
和COLUMNS
variables。
案例(1)或(3)足以解释行为; 引入时间延迟和比赛不这样做。