The "\e" escape sequence is recognised by at least bash versions of echo & printf, GNU coreutils /usr/bin/{echo,printf} and the GNU C compiler.
Now that printf suddenly became a builtin, it's important to not break people's scripts, or just not be worse than people are used to. Besides, the fish version of echo supports it!
I don't think "\e" is posix (dash and busybox don't support it), but when GNU standards deviate from posix, it's usually for a reason.
A patch that works for me:
diff --git a/builtin_printf.cpp b/builtin_printf.cpp index e164f81..d5cf9e0 100644 --- a/builtin_printf.cpp +++ b/builtin_printf.cpp @@ -26,6 +26,7 @@ \a = alert (bell) \b = backspace \c = produce no further output + \e = escape \f = form feed \n = new line \r = carriage return @@ -319,6 +320,9 @@ void builtin_printf_state_t::print_esc_char(wchar_t c) case L'c': /* Cancel the rest of the output. */ this->early_exit = true; break; + case L'e': /* Escape. */ + this->append_output(L'\e'); + break; case L'f': /* Form feed. */ this->append_output(L'\f'); break; @@ -369,7 +373,7 @@ long builtin_printf_state_t::print_esc(const wchar_t *escstart, bool octal_0) esc_value = esc_value * 8 + octal_to_bin(*p); this->append_format_output(L"%c", esc_value); } - else if (*p && wcschr(L"\"\\abcfnrtv", *p)) + else if (*p && wcschr(L"\"\\abcefnrtv", *p)) print_esc_char(*p++); else if (*p == L'u' || *p == L'U') {
(There shall be 3 tabs between case labels and comments, looks like they became spaces)