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.
However, my 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(\r
)!
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 -t
or --tty=true
.
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
.
It seems that the default behavior of tty is to add the carriage return.
In my case, I did not actually need STDIN
nor TTY
, so I ran the container without -it
:
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:
Delete \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.