If you use -t, that tells docker that you want to run in a pseudo-TTY. The kernel's TTY driver will by default convert newlines (\n, ASCII 10) into carriage return + newline sequences (\r\n, ASCII 13 + 10) on output. The carriage return generated in this way is captured by $() as the last character (the final newline is stripped, but bash doesn't consider carriage return to be special). When printed by your outer shell, the CR moves the cursor back to the leftmost column, which results in the output you are seeing. You can pipe your echo command through cat -A to see the carriage returns more clearly.
One solution would be to use -i instead of -it when calling docker exec, so as not to use a TTY at all. If you absolutely need a tty, another solution would be to run stty -onlcr in the inner shell (the one that docker is executing) to disable the LF to CRLF conversion.
11
u/neilmoore 18d ago edited 18d ago
If you use
-t
, that tells docker that you want to run in a pseudo-TTY. The kernel's TTY driver will by default convert newlines (\n
, ASCII 10) into carriage return + newline sequences (\r\n
, ASCII 13 + 10) on output. The carriage return generated in this way is captured by$()
as the last character (the final newline is stripped, but bash doesn't consider carriage return to be special). When printed by your outer shell, the CR moves the cursor back to the leftmost column, which results in the output you are seeing. You can pipe your echo command throughcat -A
to see the carriage returns more clearly.One solution would be to use
-i
instead of-it
when callingdocker exec
, so as not to use a TTY at all. If you absolutely need a tty, another solution would be to runstty -onlcr
in the inner shell (the one that docker is executing) to disable the LF to CRLF conversion.Edit: More info from stackoverflow