anordal · GitHub

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)

Read the original on github.com ↗