bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ${var@P} expansion includes 0x01 and 0x02


From: Dennis Williamson
Subject: Re: ${var@P} expansion includes 0x01 and 0x02
Date: Mon, 9 Nov 2015 18:53:05 -0600



On Fri, Nov 6, 2015 at 7:51 AM, Chet Ramey <chet.ramey@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    chet@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

[Prev in Thread] Current Thread [Next in Thread]