Wednesday 6 February 2019

Escape non-printing characters in a function for a Bash prompt


In a Bash Prompt (PS1 variable), I'm calling a function to potentially add text to the prompt: export PS1="\u@\h \$(my_function) \$ "


However, the function in the prompt contains ANSI color codes that change based on the output of the function (sometimes red, sometimes green). Adding "\[" to the PS1 variable should escape those codes as non-printing, but if I do an echo in the function, the "\[" get printed literally in the prompt.


How can I escape these ANSI color codes from within a function for use in a bash prompt?



Answer



The readline library accepts \001 and \002 (ASCII SOH and STX) as non-printable text delimiters. These also work in any application that uses readline.


From lib/readline/display.c:243 in bash source code:


243 /* Current implementation:
244 \001 (^A) start non-visible characters
245 \002 (^B) end non-visible characters
246 all characters except \001 and \002 (following a \001) are copied to
247 the returned string; all characters except those between \001 and
248 \002 are assumed to be `visible'. */

The bash-specific \[ and \] are in fact translated to \001 and \002 at y.tab.c:7640.




Note: If you use bash's printf or echo -e, and if your text has \001 or \002 immediately before a number, you'll hit a bash bug that causes it to eat one digit too many when processing octal escapes – that is, \00142 will be interpreted as octal 014 (followed by ASCII "2"), instead of the correct octal 01 (followed by ASCII "42"). For this reason, use hexadecimal versions \x01 and \x02 instead.


No comments:

Post a Comment

Where does Skype save my contact's avatars in Linux?

I'm using Skype on Linux. Where can I find images cached by skype of my contact's avatars? Answer I wanted to get those Skype avat...