Raw ^M in xtrace output

Marcel Schnippe <[email protected]> Sun, 15 Mar 2026 16:17:39 +0100
Newsgroups gmane.comp.shells.bash.bugs
Message-ID <[email protected]>
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fno-omit-frame-pointer 
-mno-omit-leaf-frame-pointer -flto=auto -ffat-lto-objects 
-fstack-protector-strong -fstack-clash-protection -Wformat 
-Werror=format-security -fcf-protection -Wall
uname output: Linux Trillian 6.17.0-14-generic #14~24.04.1-Ubuntu SMP 
PREEMPT_DYNAMIC Thu Jan 15 15:52:10 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.2
Patch Level: 21
Release Status: release

Description:
         bash xtrace (set -x) inconsistently quotes \r (0x0D) in traced 
values. When \r is embedded mid-string,
         xtrace wraps in single quotes with raw 0x0D bytes instead of 
using $'\r' escaping. This breaks tooling that
         processes xtrace output line-by-line

Repeat-By:
         #!/usr/bin/env bash
         set -x
         while IFS= read -r line; do
                 printf '%s\n' "$line"
         done < <(printf '(Reading database ... )\r(Reading database ... 
50%%)\r(Reading database ... 100%%)\n')

         ./test.sh 2>&1 | cat -A # shows raw ^M in xtrace +printf output 
instead of $'\r' escaping like in ++printf.
         + IFS=$
         + read -r line$
         ++ printf '(Reading database ... )\r(Reading database ... 
50%%)\r(Reading database ... 100%%)\n'$
         + printf '%s\n' '(Reading database ... )^M(Reading database ... 
50%)^M(Reading database ... 100%)'$
         (Reading database ... )^M(Reading database ... 50%)^M(Reading 
database ... 100%)$
         + IFS=$
         + read -r line$

Fix:
         xtrace should use $'...' quoting consistently when the value 
contains control characters,
         as it already does in most cases (e.g. trailing \r from read).

Social: Hey Chet,
Hope you are doing well? Thank you for supporting Bash. I love it!
Best regards,
Marcel