Passing -t to docker run will set the TERM environment variable. Doing so to docker exec will not. This causes things like htop to not work.
$ docker run -d --name foo debian bash -c "while true; sleep 1; done"
2fc4a0d2fc6d
$ docker exec -ti foo env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=2fc4a0d2fc6d
Or a case that the end user is more likely to experience:
$ docker run -d --name foo debian bash -c "while true; sleep 1; done"
2fc4a0d2fc6d
$ docker exec foo "apt-get update && apt-get install -y htop"
....
$ docker exec -ti foo htop
Error opening terminal: unknown.
Versions and stuff:
$ docker version
Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa
$ uname -a
Linux hostname 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ docker -D info
Containers: 186
Images: 2828
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 3206
Execution Driver: native-0.2
Kernel Version: 3.13.0-35-generic
Operating System: Ubuntu 14.04.1 LTS
Debug mode (server): false
Debug mode (client): true
Fds: 135
Goroutines: 224
EventsListeners: 1
Init Path: /usr/bin/docker
WARNING: illegal base64 data at input byte 4
WARNING: No swap limit support
Apologies if this has already been reported/fixed (I didn't test against master, even though I know I should!)
@bluepeppers i think this is fixed in master.
I don't think so. Doing some more digging, this is actually a dupe of #8631, though I'm not sure I really accept the conclusion in that issue that this is expected behaviour. The primary use case of docker exec is debugging running containers, and I know I don't habitually run my containers with -t everywhere, making docker exec a whole lot less useful. It also contradicts the principle of least surprise, imo: I would expect the terminal to behave in the same way using docker run -t and docker exec -t.
I'm tempted to agree with you - at bare minimum, if we do accept the assertion by @cpuguy83 and @jfrazelle , they should have added some documentation explaining it.
I got bitten by this issue. I finally got round to removing sshd from my containers now that all our servers have docker v1.3 and docker exec is available to do inspection and debugging. The problem is I do not run the main containers with -t and so when I get a shell into them with docker exec I have a dumb terminal
echo $TERM
dumb
less /etc/passwd
WARNING: terminal is not fully functional
I'm looking for a workaround. Doing reset doesn't seem to work:
reset
xterm
...
less /etc/passwd
WARNING: terminal is not fully functional
workaround: use nsenter: https://github.com/jpetazzo/nsenter
It works
maybe the documentation need to add -t to run command for all the use of of docker run and explain that is to make sure that docker exec work the correct way ...
+1. docker exec basically is for "exceptional" cases. Having to start a container with -t for exceptional cases doesn't seem logical to me.
Workaround:
I've tested this on a OSX host with boot2docker vm.
Note, this will not survive restarts.
closing as dup of https://github.com/docker/docker/issues/8755
Workaround:
docker exec -it $container /bin/bash -c "export TERM=xterm; exec bash"
Works very well.
I find it easier to remember:
docker exec -ti test env TERM=xterm bash -l
:+1:
👍
kramarama is very to remember
@jfrazelle this isn't a duplicate, can you reopen?
This issue is about an environment variable (TERM) differing inside docker exec depending on whether you initially started the container with -t or not.
@samshiles's answer is worked for me.
Just encountered the same issue.
At least the doc could mention that "-t" has a slightly different effect with "run" and with "exec".
What is misleading is that:
It would be nice if we could pass multiple environment variables (ala -e)
I confess we're seriously abusing the exec api to avoid giving ssh to people to do things they shouldn't be doing in a production environment - containers should be treated as immutable black boxes, if you can't diagnose from logs then you're doing logging wrong - all the arguments, I've had them.
@freman The production environment is the last step of a container workflow. Before you have your perfect black production box there's a lot of work you have to do with exec.
@vipseixas we've been doing this for almost two years, it's literally "let the devs tinker with their php in production" type work (because face it, it's easier to syntax error 30 live instances of the site in docker than it is to work offline, test, etc), the rest of everything is stable. The problem is as the exec api stands it's not suitable for doing that at least not on a production machine. No tidy way to clean up after someone that just closes their terminal instead of exiting properly, no tidy way to pass env, probably more I'm forgetting after so little sleep. I have been trying to write a tool that lets us exec right into a shell the thing remotely (ala ssh but reverse proxied so there's no ports exposed, with full session recording, and easier to integrate auth) but these issues make it un-appealing
any chance to get this one fixed, to make using docker exec more comfortable?
FYI terminal copy + cols/rows fix
kubectl exec -it $1 -- /bin/bash -c "stty rows $(tput lines) cols $(tput cols) && export TERM=$TERM && exec bash"
https://github.com/grosser/dotfiles/commit/eca07c9c69deccdc19a5bcaf7b46b72f14577711
We just merged a pull-request that automatically sets TERM if docker exec is started with a tty (-t) https://github.com/docker/docker/pull/26461
This change will go into the next release (1.13)
@thaJeztah Thanks! What about docker-compose exec? I can't use -t option there...
@bocharsky-bw docker-compose should use the same API, but if it's not working with the 1.13 daemon, it's best to open an issue in the docker-compose issue tracker; https://github.com/docker/compose/issues
我今天也遇到这个问题,估计是TERM的问题。谢谢。
Google translate;
I have encountered this problem today, it is estimated that the problem of TERM. Thank you.
Works like a charm
kubectl exec -it kafka-kafka-0 -- bash -c "export TERM=xterm; exec bash"
or
kubectl exec -it kafka-kafka-0 -- bash -c "export TERM=xterm; bash"
docker exec -it $container /bin/bash -c "export TERM=xterm; exec bash"
Most helpful comment
Workaround:
I've tested this on a OSX host with boot2docker vm.
Note, this will not survive restarts.