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 \ede 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 \een 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, REDy 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 PS1con 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 PS1para incluir \[y \]alrededor de las secuencias de escape de color, p. Ej.
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
No se puede usar get_exit_statuscorrectamente 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}_IGNOREque 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}\].\ey\033(y\[/\],\uy\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} ', laPS1variable se establece en${RED}\h $(get_path) ${exitStatus}${NONE}, donde solo\hhay 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\esecuencias a personajes de escape reales.Cuando ejecuta
PS1="${RED}\h $(get_path) ${exitStatus}${NONE} ", laPS1variable se establece en\e[1;31m\h PATH 0\e[m. Las variablesRED,exitStatusyNONEse expanden en el momento de la asignación. Entonces el indicador contiene tres secuencias de escape rápidas (\e,\hy\ede 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.\wes una secuencia de escape integrada para imprimir el directorio actual.$?en el indicador si no tiene unoPROMPT_COMMANDen primer lugar.fuente
PS1está mal, pero el consejo para el uso$'...'deREDyGREENdebe 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
$PS1es 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
$PS1es que un host tiene un$PROMPT_COMMANDconjunto 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