Los problemas:
Abra la línea de comando:
Ingrese la letra varias veces:
En lugar de ajustarse a una nueva línea, el texto ingresado se ajusta a la misma línea:
Ahora, comience a presionar b. La segunda vez que se requiere un ajuste de línea, se ajustará a una nueva línea:
¿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;35m
Son 7 caracteres. bash
No 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 readline
el 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 bash
se reconoce \e
como 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 zsh
tiene 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 red
si se produce un error, en verde, de lo contrario se podría escribir:
PS1='%F{%(?:green:red%)}blah%f $ '
tcsh
tiene %B
, pero no %F{color}
. Entonces ahí usarías:
set prompt = '%{\e[1;35m%}blah $ '
En ksh88
o 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).
ksh93
utiliza 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 esteterminator
por ejemplo). Un efecto secundario si tiene un mensaje con secuencias de control es que las tabulaciones no estarán alineadas correctamente.