Recently, I was writing a script whose function was to retrieve and parse a list of processes that were running in a docker container.
The script was based on another script that did the same by
ssh-ing to a remote server.
grep/sed/awk command set did not work despite the printed output in the terminal looked identical to the one from the original script.
This is a simplified version of the command:
1 2 $docker exec -it container_name echo "Hello” Hello
As you may see, the output looks very normal. I decided to print the output with C-styled escaped characters using the od utility:
1 2 3 $docker exec -it container_name echo "Hello" | od -c 0000000 H e l l o \r \n 0000007
You may notice that the output contains the carriage return character(
In contrast, the
ssh output does not:
1 2 3 $ssh user@remote_server "echo Hello" | od -c 0000000 H e l l o \n 0000006
In order to understand where the difference comes from, we need to take a look at the parameters of
docker exec -it.
By default, docker containers have only
STDOUT attached, therefore a container’s output is printed to the host’s terminal.
If a user needs to send an input to the container, the container has to have
STDIN open. In order to do so, you need to run
docker exec -i or
docker exec --interactive=true.
It is likely that most applications don’t need more parameters except those that use the
TTY features, such as text coloring or
curses. To provide them with this ability, the container has to run with
A good example of such an application is
vim. The only way to use
vim inside a container is to run/execute the container with
It seems that the default behavior of tty is to add the carriage return.
In my case, I did not actually need
TTY, so I ran the container without
1 2 3 $docker exec container_name echo "Hello" | od -c 0000000 H e l l o \n 0000006
The result is no carriage return!
In case you do need
TTY but don’t want the carriage return, there are a few options:
\r from the container’s output using tr:
1 2 3 $docker exec -it container_name echo "Hello" | tr -d '\r' | od -c 0000000 H e l l o \n 0000006
Configure the container’s
TTY to translate newline to carriage return-newline:
1 2 3 $docker exec -it container_name /bin/bash -c "stty -onlcr && echo 'Hello'" | od -c 0000000 H e l l o \n 0000006
Note: all of the above applies to
docker run as well.
Please share your thoughts on LinkedIn.