skip to Main Content

I’m trying to write a wrapper over Docker to propagate signals and standard output in a sensible way. First, Docker doesn’t handle SIGPIPE nicely:

$ docker run --rm ubuntu yes | head
y
y
y
y
y
y
y
y
y
y
write /dev/stdout: broken pipe
$ 

The extra output "write /dev/stdout: broken pipe" would be fine even if a little annoying, but the Dockerized process isn’t stopped. I wrote a wrapper to mount a FIFO as a volume and redirect the command’s standard output:

fifo=`basename $0`.$$
mkfifo $fifo
cat $fifo &
docker run --rm -v$PWD/$fifo:$PWD/$fifo ubuntu sh -c "$* >$PWD/$fifo"
rm $fifo

This does what I’m hoping for standard output; however, now, ctrl-C won’t stop the container. Apparently the shell won’t send SIGINT to the foreground child. I expected the following to work around this latest issue:

trap 'kill $!' INT TERM
fifo=`basename $0`.$$
mkfifo $fifo
cat $fifo &
docker run --rm -v$PWD/$fifo:$PWD/$fifo ubuntu sh -c "$* >$PWD/$fifo" &
wait
rm $fifo

However, on ctrl-C, the script exits, with the Dockerized process (and cat) continuing to spray output on my terminal.

Is it clear what I’m trying to do? I’m a big fan of UNIX workflow, but a lot of modern projects are depending on Docker (to do what the OS should already be doing). More specifically, I’m trying to benchmark a few Docker applications that are using a shared resource. I’d like to terminate one instance once it has output a certain number of lines and terminate all the other instances by sending SIGTERM.

2

Answers


  1. Chosen as BEST ANSWER

    One solution is to kill the cat background child rather than the Docker background child in the trap handler. Eventually, the Docker process gets a SIGPIPE, which works because of the FIFO volume.

    I'm guessing somehow the Docker daemon doesn't propagate SIGTERM to the underlying process in this script.

    There's gotta be something cleaner...


  2. Another solution is to use docker run‘s –detach option and then docker stop the container in the trap handler.

    fifo=`basename $0`.$$
    trap 'rm -f $fifo && docker stop $docker' INT TERM
    mkfifo $fifo
    docker=`docker run --detach --rm -v$PWD/$fifo:$PWD/$fifo ubuntu sh -c "$* >$PWD/$fifo"`
    cat $fifo
    rm $fifo
    

    Could the FIFO volume be replaced with a docker kill --signal=PIPE solution?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search