我想知道如何更改以下行为。我们说我的终端有 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
时,尽管我的终端尺寸很大,但总是给我24 。这不仅适用于ubuntu容器,我还尝试使用debian(docker run --rm -it debian tput lines
)并且我的结果相同24。
这样做的目的是使用考虑终端中线路的mdp presentation tool。当我的实施失败时,我尝试了其他人docker implementation,但我遇到了同样的错误。
这是我在图片中的错误:
有没有人知道它可能是什么以及如何解决这个问题?
答案 0 :(得分:43)
您现在可以使用以下命令安装goinside
命令行工具
sudo npm install -g goinside
然后进入具有正确终端大小的docker容器:
goinside docker_container_name
感谢@VonC answer我们通过我们放入~/.profile
的简单bash片段找到了解决此问题的方法:
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside
现在你可以进入一个没有终端尺寸问题的docker容器:
$ goinside containername
source ~/.profile
函数之前, 记住到goinside
。
(因为它在下面的评论中共享)如果您要为goinside
启用自动完成功能,您可以在.profile
中使用此代码段:
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
_goinside(){
COMPREPLY=( $(docker ps --format "{{.Names}}" -f name=$2) );
}
complete -F _goinside goinside;
export -f goinside;
如果您使用zsh
作为默认终端,则可以在~/.zshrc
文件中使用此代码段:
autoload bashcompinit
bashcompinit
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
_goinside(){
COMPREPLY=( $(docker ps --format "{{.Names}}" -f name=$2) );
}
complete -F _goinside goinside;
export goinside;
答案 1 :(得分:16)
2018年9月更新:检查docker 18.06是否有同样的问题(it should not,moby/moby
issue 33794之后,以及moby/moby
issue 35407和PR 37172是{{3}的一部分}})。
2016:
CMD ["/bin/bash"]
这意味着默认ENTRYPOINT
为sh -c
(我怀疑tput line
在sh
会话中运作良好,因为Ubuntu Dockerfile使用terminfo
数据库,可能只为该图像中的bash设置)
您可以尝试使用ENTRYPOINT
覆盖bash -c
并检查其是否更有效。
但是从命令行开始不起作用:
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。
实际上,以下始终使用以下内容返回“not 24”:
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash", "-l", "-i", "-c" ]
docker run --rm -it u -c 'sleep 0.1; ls; tput lines'
48
docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines"
鉴于睡眠成功,我怀疑docker使用running命令旋转容器,一旦启动,客户端就会连接到正在运行的容器。 通常需要几毫秒的时间。
这给了我另一个想法:
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
附加会话中的tput lines
工作正常
(在drmae
别名上,请参阅“below”)
How to remove old and unused Docker images添加thajeztah:
创建容器,然后使用默认值(
80x24
)启动,之后(-it
时),附加会话。
会话指定终端的大小;
请参阅“in the comments”API。
DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee43a/resize?h=46&w=221
有关详情,请参阅Resize a container TTY 它与docker issue 25450有关。 issue 10341 "Container create or start should accept height/width params"添加了( 2016年9月):
这实际上已经在runtime-spec(Aleksa Sarai (cyphar))中再次出现 基本上,由于Windows需要能够在首次启动时设置控制台大小,我们最终可能会为所有平台添加。
opencontainers/runtime-spec PR 563指出OP silgon中的代码:
// 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上使用此属性是否有意义,并使用该值设置初始控制台大小?
api/client/container/run.go
就在它上面,一个新的补丁可以转到Kenfe-Mickaël Laventure (mlaventure
)。
答案 2 :(得分:2)
here:在容器内运行bash而不遇到线路问题的一种好方法:
docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash
答案 3 :(得分:1)
关于sh
与terminfo的评论在很大程度上是无关紧要的。相关部分(在给定答案中不清楚)是命令执行的方式。 tput
按以下顺序检查三个功能(使用setupterm
):
TERM=xterm
为 24 80 ), LINES
和COLUMNS
环境变量。在没有交互式shell 的情况下运行的命令可以以阻止获取当前窗口大小的方式执行。例如,这是ssh
(-t
选项)的一项功能。此外,Docker可能(尽管毫无意义)设置LINES
和COLUMNS
变量。
情况(1)或(3)足以解释行为;引入时间延迟和比赛不会那样做。
答案 4 :(得分:1)
它已在docker 18.06中修复:https://github.com/moby/moby/issues/33794#issuecomment-406814439
答案 5 :(得分:1)
我刚刚测试了版本Docker version 18.06.1-ce, build e68fc7a
。似乎有同样的问题。但是,github issue中的一个人给了practical workaround:
docker run --rm -it -e COLUMNS=$COLUMNS -e LINES=$LINES -e TERM=$TERM -it ubuntu:16.04 tput lines