En mi .bashrc
, uso códigos de color de terminal ANSI para colorear varios bits. Se parece a esto:
PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '
donde virtual_env
y git_branch
son funciones bash que generan cosas en stdout.
Ahora, para que sea más fácil de leer y modificar, me gustaría almacenar los códigos de color en variables y referirme a ellos, en lugar de incrustarlos directamente PS1
. Entonces tengo un montón de variables como esta:
GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"
Me gustaría poder escribir algo como:
PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '
Pero esto no funciona: los códigos de color aparecen en el mensaje, como si hubieran escapado. Los colores funcionan correctamente si uso comillas dobles en su lugar PS1
, pero luego el aviso solo cambia cuando lo hago source ~/.bashrc
.
He intentado otras cosas que he visto hacer a la gente: usar printf
, usar comillas simples para los colores, poner el \[
y \]
en PS1
lugar de la variable de color, pero nada parece funcionar.
¿Cómo puedo usar variables para los códigos de color?
fuente
.bashrc
?Respuestas:
La solución es hacer que el shell sustituya las variables de color al definir el indicador, pero no las funciones. Para hacer esto, use las comillas dobles como había intentado originalmente, pero escape de los comandos para que no se evalúen hasta que se dibuje el mensaje.
Observe el
\
antes de$()
en cada comando.Si hacemos eco de esto, vemos:
Como puede ver, las variables de color se sustituyeron, pero no los comandos.
fuente
El problema es que tu variable
GREEN
contiene la cadena literal que consiste en "barra diagonal inversa barra invertida cero tres tres" y así sucesivamente. No contiene, por ejemplo, un carácter de escape ASCII como se requiere para que su terminal cambie de color.Se puede poner en caracteres de control
GREEN
(yYELLOW
, yRESET
) de forma manual, pero una opción mucho mejor es utilizartput
en primer lugar, por lo que no es necesario codificar nada y va a apoyar cualquier tipo de terminal.La razón por la cual el mundo cuando pones "barra invertida cero tres tres", etc ... directamente
PS1
es que la interpretación de ciertas secuencias de barra invertida es una característica de la incitación de bash (vea la sección PROPUESTA en el manual. Esta sustitución ocurre antes de la expansión de parámetros, comando sin embargo, la sustitución aritmética y la eliminación de comillas no se aplican a los resultados de todas esas otras operaciones.fuente
\[\]
dentro del$PS1
. Por ejemplo:PS1='\u@\h:\w\[${YELLOW}\]'
. Si no haces esto y terminas con un comando largo que pasa a la siguiente línea, encontrarás todo tipo de problemas. El shell utiliza\[\]
para determinar qué caracteres no se pueden imprimir, por lo que no los tiene en cuenta en el cálculo de la longitud de la solicitud. Necesita esto para poder dibujar la línea correctamente cuando excede el ancho del terminal.tput
, gracias. Usaré la respuesta de Patrick por ahora, pero volveré a ver esto cuando tenga la oportunidad.Cambie la forma en que llena $ GREEN, $ YELLOW y $ RESET:
fuente
\[…\]
bit debe permanecer en el indicador, no puede rellenarlo en una variable. Lo ha eliminado por completo, lo que provocará problemas de visualización (el cursor no está en la posición donde bash lo espera).tput setaf
no le permite elegir entre el conjunto de colores "claros", como el cian claro. La respuesta de @ Cyrus, sin embargo, sí.