bashdockershelltty

Why does my terminal not perform carriage returns while docker is running?


I have a shell script starting a docker container. Before starting the container, it starts a background loop printing some lines to the terminal. I noticed that these printed lines do not return the cursor to the beginning of the line. What I found out: this happens only during the lifetime of the container. See minimal example:

#!/usr/bin/env bash

cleanup() {
  kill "${BACKGROUND_PROCESS}"
}
trap cleanup EXIT

backgroundLoop() {
  while true; do
    echo .
    sleep 1
  done
}

backgroundLoop &
BACKGROUND_PROCESS=$!

sleep 2
echo Starting docker

docker run --rm -it alpine sleep 5

echo Docker has finished
sleep 2

cleanup

The output is:

.
.
Starting docker
.
.
 .
  .
   .
    .
     Docker has finished
.
.

Can anyone explain why this happens? It seems to be related to this question, I assume that docker reconfigures the current TTY and restores it afterwards. Is that correct?

Removing -t from the docker call actually fixes the problem, which seems to back my theory. However, I need the interactive TTY for my actual use case.

How can I change my code so that all output lines are printed with correct carriage returns?


UPDATE:

I got an answer to this question which solves the problem for my minimal example I posted above by calling stty -onocr in the docker container before the actual command.

My real-world scenario, however, uses a custom docker image with a bash script as entry point, so I cannot pass commands as arguments. Minimal example of the entrypoint script entrypoint.sh:

#!/usr/bin/env sh

sleep 5

Then replace the docker call in the test script

docker run --rm -it alpine sleep 5

with

docker run --rm -it -v ./entrypoint.sh:/entrypoint.sh --entrypoint /entrypoint.sh alpine

The output is the same, but the proposed fix does not work in this case. Any ideas how to apply the fix to this slightly different environment?


Solution

  • Tell the container not to add CR characters to the output by running stty -onocr in your container by changing the docker run command to

    docker run --rm -it alpine stty -onocr && sleep 5