5

I have a looped process running in a docker container that accepts typed commands. At the moment I have to use docker attach <container> and then type my command such as restart before exiting out.

I can't use docker exec as far as I know as the process is already running that I want to interact with so is there anyway I can programmatically pass in a command to docker attach?

Edit: This is a command inside of the program running, not one that's available with the shell

FortuneCookie101
  • 505
  • 1
  • 7
  • 19

3 Answers3

2

A solution might be to use something like:

echo "your input here" | docker attach <your container>

but... this requires to not use the -t option which might cause you other problems...


Check this issue: Redirect stdin to docker attach where Michael Crosby provides an example:

This issue has been resolved.

docker run -i busybox sh -c "while true; do cat /dev/stdin; sleep 1; done;"
test

# ... from another terminal
echo test | docker attach 27f04f3fd73a

What should be noticed here is that it doesn't work when you run the container with --tty , -t (Allocate a pseudo-TTY) option. I haven't understood completely why this happens so I won't try to explain it, some things have been already written here: Confused about Docker -t option to Allocate a pseudo-TTY


Also, from the docker run reference:

For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it as you’ll see in later examples.Specifying -t is forbidden when the client is receiving its standard input from a pipe, as in:

$ echo test | docker run -i busybox cat
Community
  • 1
  • 1
tgogos
  • 23,218
  • 20
  • 96
  • 128
  • I've ran into the issue with the ``-t`` flag probably being used in docker-compose, I get the error ``the input device is not a TTY`` when I try and pipe to it. – FortuneCookie101 Sep 25 '19 at 08:31
0

It's also possible to send a command to a docker container which has a terminal, using expect:

send-t.exp:

#!/usr/bin/expect -f
set container [lindex $argv 0]
set command [lindex $argv 1]
spawn docker attach $container
send -- "$command\n"
expect "*\n"
expect "*\n"
# set timeout 1
# expect eof

Usage:

send-t.exp container 'command args'

Example:

send-t.exp my-container 'find /'

Sam Watkins
  • 7,819
  • 3
  • 38
  • 38
0

As described here, you can use socat for this: echo 'restart' | socat EXEC:'docker attach <container>',pty STDIN

Another full example:

# Run the program in docker, here bash, in background
docker run -it --rm --name test ubuntu &
# Send "ls -la" to the bash running inside docker
echo 'ls -la' | socat EXEC:'docker attach test',pty STDIN
# Show the result
docker logs test
Anthony O.
  • 22,041
  • 18
  • 107
  • 163