Gilles identificó su problema principal, pero quería intentar explicarlo de manera diferente.
Bash interpreta los escapes de solicitud especiales solo antes de expandir cualquier variable en la solicitud. Esto significa que el uso \e
de una variable que se expande desde el indicador no funciona, aunque sí funciona directamente PS1
.
Por ejemplo, esto funciona como se esperaba y da texto rojo:
PS1='\e[1;31m this is in red '
Pero esto no es así, solo pone un literal \e
en el indicador:
RED='\e[1;31m'
PS1="$RED not in red "
Si desea almacenar los escapes de color en las variables, puede usar la cita ANSI-C ( $'...'
) para poner un carácter de escape literal en la variable.
Para ello, puede cambiar su definición de GREEN
, RED
y NONE
, por lo que su valor es la secuencia de escape real.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Si haces eso, tu primero PS1
con las comillas simples debería funcionar:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Sin embargo, entonces tendrás un segundo problema.
Intente ejecutar eso, luego presione Up Arrow, Homey su cursor no volverá al inicio de la línea.
Para solucionarlo, cambie PS1
para incluir \[
y \]
alrededor de las secuencias de escape de color, p. Ej.
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
No se puede usar get_exit_status
correctamente aquí, ya que su salida contiene caracteres impresos (el código de salida) y no impresos (los códigos de color), y no hay forma de marcarlo correctamente en el mensaje. Ponerlo \[...\]
lo marcaría como no impreso en su totalidad, lo cual no es correcto. Tendrá que cambiar la función para que solo imprima el código de color adecuado y luego rodearlo \[...\]
en el indicador.
\[
es\1
, y\[
es\2
. Los que corresponden a algo de readlineRL_PROMPT_{START,END}_IGNORE
que le pide que ignore los bytes al contar la longitud del indicador en la pantalla. Ver lists.gnu.org/archive/html/bug-bash/2015-08/msg00027.html .\]
es\2
? ¿Y quieres decir que por eso es necesario${exitStatus}
? Mi punto era que${exitStatus}
no contiene caracteres que no se imprimen, por lo que bash debería poder determinar correctamente cuántos caracteres mueve la solicitud sin el\[
y\]
en\[${exitStatus}\]
.\e
y\033
(y\[
/\]
,\u
y\h
) desde el indicador, solo lo hace antes de expandir las variables. EntoncesPS1='\e[1;31m red'
funciona,red='\e[1;31m'; PS1='$red red'
no.Cuando ejecuta
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
, laPS1
variable se establece en${RED}\h $(get_path) ${exitStatus}${NONE}
, donde solo\h
hay una secuencia de escape rápida. Después de expandir las secuencias de solicitud (rendimiento${RED}darkstar $(get_path) ${exitStatus}${NONE}
), el shell realiza las expansiones habituales, como las expansiones variables. Aparece un mensaje que se muestra como este\e[1;31mdarkstar PATH 0\e[m
. Nada en el camino expande las\e
secuencias a personajes de escape reales.Cuando ejecuta
PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
, laPS1
variable se establece en\e[1;31m\h PATH 0\e[m
. Las variablesRED
,exitStatus
yNONE
se expanden en el momento de la asignación. Entonces el indicador contiene tres secuencias de escape rápidas (\e
,\h
y\e
de nuevo). No hay variables de shell para expandir en esta etapa.Para ver los colores, necesita que las variables de color contengan caracteres de escape reales. Puedes hacerlo de esta manera:
$'…'
expande las secuencias de barra diagonal inversa y algunas secuencias de barra diagonal inversa como\n
, pero no incluidas\e
. Hice otros tres cambios a su solicitud:\[…\]
alrededor de secuencias que no se imprimen, como los comandos de cambio de color. De lo contrario, su pantalla terminará confundida porque bash no puede calcular el ancho de la solicitud.\w
es una secuencia de escape integrada para imprimir el directorio actual.$?
en el indicador si no tiene unoPROMPT_COMMAND
en primer lugar.fuente
PS1
está mal, pero el consejo para el uso$'...'
deRED
yGREEN
debe hacer que funcione usando las adelfas dePS1
.Tratar:
fuente
Aquí está el enfoque con el que he seguido, evita el uso de
PROMPT_COMMAND
.Entonces mi
$PS1
es el siguiente:fuente
$?
puede tener es un número entero, en realidad debería usarloprintf '%b' "$GREEN"
. Además, evite usar nombres de funciones con el prefijo__
o_
tal como los usa bash-complete.Aquí tienes : esto funciona para mí (TM) en Ubuntu y otras Linux (¿Linuxen?).
La razón para poner la detección del código de salida
$PS1
es que un host tiene un$PROMPT_COMMAND
conjunto de solo lectura antes de que se lea .bashrc.fuente
Para
PROMPT_COMMAND
, es más claro definir una función y usar eso:fuente