I would like to know how to change the following behavior. Let's say my terminal has 28 lines. Then I use the following commands:
$ 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
As you can see, even when all the results should be 28, when I'm calling the container as docker run --rm -it ubuntu:16.04 tput lines
it always gives me 24 despite the size of my terminal. This is not only with the ubuntu container, I also tried with debian (docker run --rm -it debian tput lines
) and I'm having the same result 24.
The purpose of this is to use the mdp presentation tool which takes into account the lines in your terminal. When my implementation failed, I tried some other person's docker implementation but I ran to the same error.
Here's my error in an image:
Does anyone has any idea what it could be and how can this be solved?
Update Sept. 2018: check if docker 18.06 has the same issue (it should not, after moby/moby
issue 33794, and also moby/moby
issue 35407 and PR 37172, part of the 18.06 release notes).
2016:
The Ubuntu Dockerfile includes:
CMD ["/bin/bash"]
That means the default ENTRYPOINT
is sh -c
(and I doubt tput line
works well in a sh
session, since tput uses terminfo
database, which might be set only for bash in that image)
You could try overwrite ENTRYPOINT
with bash -c
and check if that works better.
That does not work from command line though:
docker run --entrypoint /bin/bash --rm -it ubuntu:16.04 -i -c 'tput lines'
24
I will check the option of defining a custom image.
FROM ubuntu:16.04
ENTRYPOINT ["/bin/bash", "-c"]
The result is the same though:
docker run --rm -it u 'tput lines'
24
This however "works":
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash" ]
With:
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
There might be a synchronization issue, as the same command does return 24 from time to time.
Actually, the following always return "not 24" with:
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash", "-l", "-i", "-c" ]
docker run --rm -it u -c 'sleep 0.1; ls; tput lines'
48
The OP silgon proposes in the comments:
docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines"
Given the success of sleep my suspicion is that docker spins up the container with the running command, and once up, the client attaches to the running container. Typically something that takes milliseconds.
That gave me another idea:
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
A tput lines
within an attached session works just fine.
(On the drmae
alias, see "How to remove old and unused Docker images")
thajeztah adds in the comments:
the container is created, then started with the defaults (
80x24
), and after that (when-it
), a session is attached.
The session is specifying the size of the terminal;
See "Resize a container TTY" API.
DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee43a/resize?h=46&w=221
For more, see docker issue 25450.
It is related to issue 10341 "Container create or start should accept height/width params". Aleksa Sarai (cyphar) adds (Sept. 2016):
This has actually popped up again inside the runtime-spec (opencontainers/runtime-spec PR 563).
Basically, since Windows requires the ability to set the console size on first start, we might end up adding it for all platforms.
The OP silgon points out to the code in 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()
}
With the logical question:
would it make sense to use this property on Linux as well, and set the initial console size using that value?
Kenfe-Mickaël Laventure (mlaventure
) is on it, and a new patch could make it to Docker 1.13.