JSNinja
JSNinja

Reputation: 313

How to get back into shell started with docker exec?

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

Answers (1)

Nick ODell
Nick ODell

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

Related Questions