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.

Reply via email to