Docker Community Forums

Share and learn in the Docker community.

Docker exec - how to separate stderr and stdout?

I can’t find an option or some other way to separate STDERR and STDOUT when I exec something inside a container.

This is critical since when you run for example a dump command inside a container, you get error messages among the data of the dump. E.g.:

$ docker exec -it container_name bash -c -i "cd ./web; ../vendor/bin/drush sql-dump" > dump.sql

In other words docker utility just merges those streams. So this:

$ docker exec -it container_name bash -c -i ">&2 echo Error" 2>/dev/null

prints Error, but we’re not expecting it. The expected behavior would be to output NULL, as in here:

$ bash -c -i ">&2 echo Error" 2>/dev/null  # Null

This is on the surface, and I really wonder why it doesn’t work.

P.S

I should add that this has a simple workaround, just hardcode 2>/dev/null inside your call, e.g:

$ docker exec -it container_name bash -c -i "cd ./web; ../vendor/bin/drush sql-dump 2>/dev/null" > dump.sql

but this way you lose the flexibility to manage streams from the outside, for instance if you use a sort of wrapping scripts like in my case:

$ docker exec ${args['options']} ${container} bash -c -i "cd ${args['directory']}; ${args['command']} ${args['args']}"

This wouldn’t save you however if your container’s shell init scripts (e.g. .bashrc) would message something to STDERR.

1 Like

I also would like docker to seperate the streams.
In my case I am using docker exec in my cron setup where I would only want stderr to be printed and stdout to be piped to /dev/null in order to only receive mails on error.

Thanks for your workaround though! It’s working like a charm.

Try removing the ‘-t’ or ‘–tty’ option.
For example:

docker run --interactive --rm busybox /bin/sh -c 'echo OUT; echo ERR 1>&2; exit 3' >/dev/null; echo "Exit $?"

docker run --interactive --rm busybox /bin/sh -c 'echo OUT; echo ERR 1>&2; exit 3' 2>/dev/null; echo "Exit $?"