Reputation: 313
If you start a new shell in a container with docker exec
, then exit with ctrl+p ctlr+q, that shell is still running. However if you use docker attach
it attaches to the shell at PID 1, not the one started with docker exec. How do you get back into it? If there's no way to get back into it, then when would you ever exit and leave it running like this?
Upvotes: 1
Views: 4913
Reputation: 25180
I don't believe there's a Docker-native way of doing this. However, there is a general Linux tool that can re-attach terminals: reptyr. Here's an example of how to use it in Docker.
First, to show this, create a test container with a non-shell process as PID 1.
docker run -d ubuntu sleep 1h
Run docker ps
to get the container ID.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
15d0d2c918be ubuntu "sleep 1h" 3 seconds ago Up 2 seconds vigilant_raman
Next, get a shell inside it.
docker exec -it 15d0d2c918be bash
Now, to mark the shell so we know if we got back to the right one, run this command:
root@15d0d2c918be:/# export PS1='findme> '
findme>
This is the shell we're going to try to get back. Detach with Ctrl-P, Ctrl-Q.
Next, get another shell.
docker exec -it 15d0d2c918be bash
Next, install reptyr. This step is Ubuntu-specific; if you use a different OS for your container you'll need to use something else.
root@15d0d2c918be:/# apt-get update
[...]
root@15d0d2c918be:/# apt-get install reptyr
[...]
Next, find the PID of the process to reattach. You're looking for a low-numbered bash process. (Or whichever shell you're using.)
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 sleep 1h
7 pts/0 Ss+ 0:00 bash
15 pts/1 Ss 0:00 bash
269 pts/1 R+ 0:00 ps -ax
We want to attach to PID 7. (PID 15 is our own process ID. You can check the process ID of the current shell by running echo $$
.)
Next, create a file at /dev/console
. It seems that this step is only necessary when PID 1 is not a console. If the Docker container was launched with a tty, then this step is not required. If you skip this, you'll get the error [-] Unable to stat /dev/console
from repytr.
touch /dev/console
Next, get the console back. Use the PID you found previously.
root@15d0d2c918be:/# reptyr 7
[-] Timed out waiting for child stop.
findme>
And now you have the original shell back.
Upvotes: 5