sil*_*gon 34 bash terminal docker tput
我想知道如何更改以下行为.假设我的终端有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
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,即使所有结果都应该是28,当我调用容器时,docker run --rm -it ubuntu:16.04 tput lines尽管我的终端大小,它总是给我24.这不仅仅是ubuntu容器,我也尝试过使用debian(docker run --rm -it debian tput lines)并且我得到了相同的结果24.
这样做的目的是使用mdp演示工具,它考虑了终端中的行.当我的实现失败时,我尝试了其他人的docker实现,但我遇到了同样的错误.
这是我在图像中的错误:
有谁知道它可能是什么以及如何解决这个问题?
Soo*_*ena 45
您现在可以安装goinside命令行工具:
sudo npm install -g goinside
Run Code Online (Sandbox Code Playgroud)
并进入具有适当终端尺寸的docker容器内:
goinside docker_container_name
Run Code Online (Sandbox Code Playgroud)
感谢@VonC的回答,我们通过一个简单的bash片段为这个问题找到了解决方案~/.profile:
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside
Run Code Online (Sandbox Code Playgroud)
现在你可以进入一个没有终端尺寸问题的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;
Run Code Online (Sandbox Code Playgroud)
如果您使用的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;
Run Code Online (Sandbox Code Playgroud)
Von*_*onC 16
更新2018年9月:检查是否泊坞窗18.06有同样的问题(它不应该,以后moby/moby发行33794,以及moby/moby发行35407和PR 37172,该部分18.06发行说明).
2016年
CMD ["/bin/bash"]
Run Code Online (Sandbox Code Playgroud)
这意味着默认ENTRYPOINT是sh -c(我怀疑tput line在sh会话中运行良好,因为tput使用terminfo数据库,可能只为该图像中的bash设置)
你可以尝试覆盖ENTRYPOINT与bash -c和检查,如果是工作得更好.
但是,从命令行起,这不起作用:
docker run --entrypoint /bin/bash --rm -it ubuntu:16.04 -i -c 'tput lines'
24
Run Code Online (Sandbox Code Playgroud)
我将检查定义自定义图像的选项.
FROM ubuntu:16.04
ENTRYPOINT ["/bin/bash", "-c"]
Run Code Online (Sandbox Code Playgroud)
结果是相同的:
docker run --rm -it u 'tput lines'
24
Run Code Online (Sandbox Code Playgroud)
然而,这"有效":
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash" ]
Run Code Online (Sandbox Code Playgroud)
附:
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
Run Code Online (Sandbox Code Playgroud)
可能存在同步问题,因为同一命令会不时返回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
Run Code Online (Sandbox Code Playgroud)
docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines"
Run Code Online (Sandbox Code Playgroud)
鉴于睡眠成功,我怀疑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
Run Code Online (Sandbox Code Playgroud)
一个tput lines附加的会话中工作得很好.
(在drmae别名上,请参阅" 如何删除旧的和未使用的Docker镜像 ")
创建容器,然后使用defaults(
80x24)启动,之后(when-it)启动会话.
会话指定终端的大小;
请参阅" 调整容器TTY大小 "API.
DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee4??3a/resize?h=46&w=221
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅docker issue 25450.
它与问题10341"容器创建或启动应接受高度/宽度参数"有关.Aleksa Sarai(cyphar)补充说(2016年9月):
这实际上已经在runtime-spec(opencontainers/runtime-spec PR 563)中再次出现.
基本上,由于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()
}
Run Code Online (Sandbox Code Playgroud)
有逻辑的问题:
在Linux上使用这个属性是否有意义,并使用该值设置初始控制台大小?
Kenfe-MickaëlLaventure(mlaventure)就在它上面,一个新的补丁可以进入Docker 1.13.
一个很好的方式,而不会遇到线路问题运行容器中使用bash是在这里:
docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash
Run Code Online (Sandbox Code Playgroud)