To be honest, I have always been confused about docker exec -it …
, docker exec -i …
and docker exec -t …
, so I decide to do a test:
docker exec -it …
:
# docker exec -it 115c89122e72 bash
root@115c89122e72:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
It works normally.
docker exec -i …
:
# docker exec -i 115c89122e72 bash
^C
The command hangs and I have to use Ctl + c to interrupt it.
docker exec -t …
:
# docker exec -t 115c89122e72 bash
root@115c89122e72:/# ls
^C
It enters the container successfully but hangs on executing the first command.
So it seems there is no point in having the docker exec -i …
and docker exec -t …
commands. Could anyone elaborate on why there exist -i
and -t
options for the docker exec
command?
The docker exec command runs a new command in a running container. The command started using docker exec only runs while the container’s primary process ( PID 1) is running, and it is not restarted if the container is restarted.
In order to execute commands on running containers, you have to execute “docker exec” and specify the container name (or ID) as well as the command to be executed on this container. As an example, let’s say that you want to execute the “ls” command on one of your containers.
When using the docker exec command, you may encounter a few common errors: The No such container error means the specified container does not exist, and may indicate a misspelled container name. Use docker ps to list out your running containers and double-check the name.
Docker runs an application in an isolated environments. Every running instance is called as container. Docker is designed to run any application with minimal operating system. Making it faster and efficient to run. We can include required library files and exclude extra things like unnecessary applications and files.
-i
, --interactive
keeps STDIN open even if not attached, which you need if you want to type any command at all.
-t
, --tty
Allocates a pseudo-TTY, a pseudo terminal which connects a user's "terminal" with stdin and stdout. (See container/container.go
)
If you do an echo, only -t
is needed.
But for an interactive session where you enter inputs, you need -i
.
Since -i
keeps stdin open, it is also used in order to pipe input to a detached docker container. That would work even with -d
(detach).
See "When would I use --interactive
without --tty
in a Docker container?":
$ echo hello | docker run -i busybox cat
hello
-i
keeps STDIN open even if not attached, what is the status of STDOUT in this case?
It is, for docker exec
, the one set by docker run
.
But, regarding docker exec
, there is a current issue (issue 8755: Docker tty is not a tty with docker exec
unfortunately your discovery only amounts to a difference between the behaviour of tty in centos6 vs ubuntu:14.04. There is still not a functional tty inside the exec - just do
ls -la /proc/self/fd/0
and see that it's a broken link pointing to apts
which doesn't exist.the actual bug we're dealing with is that certain standard libraries assume that the symlinks in /proc/self/fds/ must be valid symlinks
The problem is that the tty is created outside on the host and there is no reference to it in the container like how
/dev/console
is setup in the primary container.
One options to fix this would be allocate and bind mount thedevpts
from the host in to the containers.
Note (Q4 2017): this should been fixed by now (docker 17.06-ce).
See PR 33007.
That PR now allows (since 17.06):
zacharys-pro:dev razic$ docker run --rm -t -d ubuntu bash
83c292c8e2d13d1b1a8b34680f3fb95c2b2b3fef71d4ce2b6e12c954ae50965a
zacharys-pro:dev razic$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83c292c8e2d1 ubuntu "bash" 2 seconds ago Up 1 second xenodochial_bardeen
zacharys-pro:dev razic$ docker exec -ti xenodochial_bardeen tty
/dev/pts/1
(before 17.06, tty
was returning "not a tty
")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With