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?
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