El uso de echo -e en PS1 provoca problemas de salto de línea en el shell

El uso de echo -e en PS1 provoca problemas de salto de línea en el shell

Los problemas:

Abra la línea de comando:

ingrese la descripción de la imagen aquí

Ingrese la letra varias veces:

ingrese la descripción de la imagen aquí

En lugar de ajustarse a una nueva línea, el texto ingresado se ajusta a la misma línea:

ingrese la descripción de la imagen aquí

Ahora, comience a presionar b. La segunda vez que se requiere un ajuste de línea, se ajustará a una nueva línea:

ingrese la descripción de la imagen aquí


¿Qué causa este comportamiento?

Usar una PS1 como esta provoca el comportamiento:

ps1Color="\033[1;35m"
export PS1='$(echo -en $ps1Color) Baz $'

Tenga en cuenta que la razón por la que quiero usar eco en lugar del color directamente es porque quiero agregar el color condicionalmente según el estado de salida del comando anterior..

El uso del color directamente no provoca que se produzca este comportamiento.


Mis preguntas son:

  • ¿Cómo puedo imprimir códigos de color para usar en una PS1?usando eco?
  • Si quiero que mi PS1 tenga un color diferente de forma condicional, ¿cuál es la mejor manera de hacerlo?
  • ¿Por qué veo este comportamiento?

Actualizar

Para ser claro, realmente quiero hacer esto usando eco porque quiero cambiar el color.condicionalmente.

Esto es lo que tengo actualmente:

function setPs1Colors_start () {

    local previousExit=$?

    local ps1Color="\033[1;35m"
    local ps1FailBackground="\e[41m"

    echo -en $ps1Color

    if [[ previousExit -ne 0 ]]
    then
        echo -en $ps1FailBackground
    fi

}

function setPs1Colors_end () {
    local ps1DefaultColor="\033[0m"
    echo -en $ps1DefaultColor
}

export PS1='$(setPs1Colors_start)[$(date +%b\-%d\ %k:%M)][$(versionControlInfo)\W]\$$(setPs1Colors_end) '

Respuesta1

\033[1;35mSon 7 caracteres. bashNo puedo adivinar que esos 7 caracteres tienen en realidad un ancho nulo. Si no, pensará que tienen 7 columnas de ancho.

Este (o más bien readlineel editor de línea subyacente que usa) quiere saber cuál es la posición actual en la pantalla porque usa secuencias de posicionamiento del cursor (arriba, abajo, izquierda, derecha) para mover el cursor cuando usa las teclas de edición.

Entonces tienes que decirle cuál de los caracteres en el mensaje no mueve el cursor. Con bash, eso se hace usando \[...\]el cual le dice al caparazón que lo que hay dentro tiene ancho cero.

También tenga en cuenta que la expansión inmediata bashse reconoce \ecomo un carácter ESC, por lo que no es necesario utilizarlo echo -e. Puedes simplemente hacer:

PS1='\[\e[1;35m\] blah $ '

Si tienes que usar echo, o mejor printf, harías:

PS1='\[$(if ...; then printf "$color1"; fi)\] blah $ '

O:

PS1='$(if ...; then printf "\[$color1\]"; fi) blah $ '

En zsh, el equivalente de bash's \[...\]es %{...%}como en tcsh, pero zshtiene directivas para cambiar los atributos de los caracteres, por lo que preferirías hacer:

PS1='%B%F{magenta}blah $ '

Para primer plano en negrita y magenta. También tiene algunas formas de pruebas condicionales, incluido on $?, por lo que redsi se produce un error, en verde, de lo contrario se podría escribir:

PS1='%F{%(?:green:red%)}blah%f $ '

tcshtiene %B, pero no %F{color}. Entonces ahí usarías:

set prompt = '%{\e[1;35m%}blah $ '

En ksh88o pdksh, harías:

PS1=$(printf '\5\r\5\33[1;35m\5blah $ ')

Eso define un carácter (aquí 0x5) como elescaparpersonaje. Luego, al incluir texto entre un par de ellos, le dice al shell que no es visible. Puede usar cualquier carácter que no sea 0x5, pero no debe aparecer en el indicador y, excepto en mksh, el terminal debe ignorarlo porque el shell realmente lo escribe (junto con el carácter CR).

ksh93utiliza solo una secuencia de posicionamiento del cursor: BS(que mueve el cursor una columna hacia la izquierda). Para moverse hacia la derecha, simplemente vuelve a dibujar los mismos personajes. Por lo tanto, no necesita conocer la posición del cursor, solo el ancho de cada carácter que ingresa. Eso funciona siempre y cuando el terminal se ajuste al margen por sí solo (por lo que no funcionará correctamente con esteterminatorpor ejemplo). Un efecto secundario si tiene un mensaje con secuencias de control es que las tabulaciones no estarán alineadas correctamente.

información relacionada