On Fri, Nov 6, 2015 at 7:51 AM, Chet Ramey <chet.ra...@case.edu> wrote:
> On 11/5/15 7:45 PM, Dennis Williamson wrote: > > > That's what the \[ and \] escape sequences expand to and use to > > communicate information to readline about invisible characters in the > > prompt (RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE). If you > want to > > use the expansion of ${var@P} as, for instance, the prompt passed to > > readline when using `read -e -p prompt', those characters need to be > there. > > > > > > To follow on to what Greg said: > > > > The only way I've found to output a string containing non-printing > sequence > > delimiters using the @P transformation is to use read -e -p or to strip > the > > \[ and \] first. All the other prompt escapes work in printf or echo -e > > when using @P. > > Let's stipulate that you're talking about interactive shells here, since > line editing is turned off in non-interactive shells, and \[ and \] only > expand to \001 and \002 when line editing is enabled. (Though what I > describe here works in non-interactive shells, too.) > > You can get the results you want by toggling the `emacs' option, or `vi' > if that's what you prefer. > > Since \[ and \] expand to special readline characters only when readline > (and therefore line editing) is enabled, and you don't want them expanded, > then you should disable readline. You can disable line editing with > `set +o emacs +o vi' (whichever is appropriate). > > Run the following script to see what I mean: > > P='\[vis0\]\w\$\[vis1\] ' > > echo "${P@P}" | cat -v > set -o emacs > echo "${P@P}" | cat -v > set +o emacs +o vi > echo "${P@P}" | cat -v > > -- > ``The lyf so short, the craft so long to lerne.'' - Chaucer > ``Ars longa, vita brevis'' - Hippocrates > Chet Ramey, ITS, CWRU c...@case.edu > http://cnswww.cns.cwru.edu/~chet/ > With editing off, I find that I must delimit variables with braces. Without the braces, only the second escape sequence is output. The \] isn't terminating the variable name when editing is off. A variation of your script: #!/home/dennis/test/bash-4.4-beta/bash red=$(tput setaf 1) # ^[[31m in my terminal none=$(tput sgr0) # ^[(B^[[m in my terminal for P in '\[vis0\]\w\$\[vis1\] ' '\[$red\]Hello\[$none\] ' '\[${red}\]Hello\[${none}\] ' do echo "${P@P}" | cat -v set -o emacs echo "${P@P}" | cat -v set +o emacs +o vi echo "${P@P}" | cat -v echo '= = = = = = =' echo done Only the first and third values of P result in expected output for every echo. For the second value of P, only the second echo behaves as expected. Here is the output I get: vis0~/test$vis1 ^Avis0^B~/test$^Avis1^B vis0~/test$vis1 = = = = = = = ^[(B^[[m ^A^[[31m^BHello^A^[(B^[[m^B ^[(B^[[m = = = = = = = ^[[31mHello^[(B^[[m ^A^[[31m^BHello^A^[(B^[[m^B ^[[31mHello^[(B^[[m = = = = = = = This is for TERM=xterm. If I run it with TERM=vt100, I get similar failure. If I set redHello=xyzzy, then "xyzzy" is output where the variable name and the literal string are run together. -- Visit serverfault.com to get your system administration questions answered.